是否可以更改 NuGet 包的位置?

Posted

技术标签:

【中文标题】是否可以更改 NuGet 包的位置?【英文标题】:Is it possible to change the location of packages for NuGet? 【发布时间】:2011-05-04 19:31:19 【问题描述】:

我的大多数项目都有以下约定:

/src
    /Solution.sln
    /SolutionFolder
        /Project1
        /Project2
        /etc..
/lib
    /Moq
        moq.dll
        license.txt
    /Yui-Compressor
        yui.compressor.dll
/tools
    /ILMerge
        ilmerge.exe

您会注意到我确实将外部库放在源文件夹中。我也对使用 NuGet 非常感兴趣,但不希望在源文件夹中使用这些外部库。 NuGet 是否具有更改所有包加载到的目录的设置?

【问题讨论】:

是的,是的,是的!这正是我使用(或非常接近)的项目结构,我一直想知道 NuGet 是否可以支持它...... 我已经详细介绍了如何使用以下答案:***.com/a/19466173/564726。您通常需要从 restore 命令中删除 solutionDir 选项才能使其正常工作。 我将 .sln 放在与您的***文件夹相同的级别。 :) 【参考方案1】:

现在可以控制软件包安装到哪个文件夹。

http://nuget.codeplex.com/workitem/215

编辑: 请参阅 Phil Haack 在 2010 年 12 月 10 日晚上 11:45 发表的评论(在工作项/上面的链接中)。该支持在 1.0 中部分实现,但没有记录。

根据@dfowler: 在解决方案旁边添加一个 nuget.config 文件:

<settings>
<repositoryPath>some path here</repositoryPath>
</settings>

有a nuget package 用于创建包文件夹覆盖。

2.1 版更新

正如 Azat 所说,现在有关于如何控制包位置的官方文档。 release notes for 2.1 在 nuget.config 文件中指定以下配置(有关放置配置文件的有效位置以及分层配置模型如何工作的说明,请参阅发行说明):

<configuration>
  <config>
    <add key="repositoryPath" value="C:\thePathToMyPackagesFolder" />
  </config>
  ... 
</configuration>

这将更改您放置文件的配置级别的包文件夹(解决方案,如果您将其放在解决方案目录中,项目在项目目录中等等)。请注意,发行说明声明:

[...] 如果您的解决方案下方有一个现有的包文件夹 root,您需要在 NuGet 将包放入之前将其删除 新位置。

【讨论】:

实际上可以使用上面的配置文件。它被淡化的原因是因为我们还没有通过 UI 和其他方式启用它的工作流,所以期待一些古怪。 请参阅reviewboard.nupack.com/r/131,了解@dfowler 对 nuget.config 工作原理的完整描述。例如,有效的 nuget.config 如下所示:lib docs.nuget.org/docs/release-notes/nuget-2.1 请参阅“指定‘包’文件夹位置”段落 第二个版本适合我,我使用最新的 NuGet,现在两个解决方案可以共享同一个 repo。我认为它可能对某些人不起作用,因为他们可能使用绝对路径?似乎绝对路径与相对路径很重要。 请记住,如果从 Visual Studio 执行此操作,请在添加/修改 nuget.config 文件后重新启动 Visual Studio。我发现了这个the hard way。【参考方案2】:
    创建了一个名为“nuget.config”的文件。 将该文件添加到我的解决方案文件夹中

这对我不起作用:

<configuration>
  <config>
    <add key="repositoryPath" value="..\ExtLibs\Packages" />
  </config>
  ... 
</configuration>

这对我有用:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>

【讨论】:

只有第二种解决方案有效:docs.nuget.org/docs/reference/nuget-config-file 这取决于您使用的 NuGet 版本。 请注意,相对路径是相对于解决方案的,因此如果您的项目处于不同级别,则它将无法工作。 这适用于 VIsual Studio 2013,但如果我使用 Visual Studio 2015,它仍然会在 sln 文件附近的 packages 文件夹中安装包, @FaisalHafeez 你找到 VS 2015 的解决方案了吗?我尝试与 一起使用,但它对我不起作用。它不会覆盖默认位置。【参考方案3】:

好吧,为了其他人阅读这篇文章 - 这是我对上述无数答案的理解:

    .nuget 文件夹中的 nuget.config 文件与该文件夹相对。这很重要,因为如果您的新文件夹类似于“../Packages”,它将把它放在总是开箱即用的地方。正如@bruce14 所说,您必须改为使用“../../Packages”

    如果不启用包还原,我无法获取最新的 nuget (2.8.5) 以在标准位置之外找到包文件夹。因此,一旦启用包还原,则应将以下内容添加到 .nuget 文件夹内的 nuget.config 文件中以更改位置:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
    

    (这很重要)如果您对 nuget.config 文件中的包文件夹位置进行任何更改,您必须重新启动 Visual Studio 或关闭/重新加载解决方案以使更改生效

【讨论】:

相信我,你的第 3 点拯救了我的一天。从最后 3 个小时开始,我一直很疯狂,直到我读到你的第 3 点。 :'( 非常感谢你兄弟!【参考方案4】:

Visual Studio 2015 上 Nuget 3.2 的解决方案是:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
        <add key="repositoryPath" value="../lib" />
    </config>
</configuration>

对父文件夹使用正斜杠。 将上述文件 (nuget.config) 保存在解决方案文件夹中。

可参考here

【讨论】:

完美!适用于 Visual Studio 2015 和 Nuget 版本 3.2.0.10516 您的意思似乎是正斜杠..但如果解决方案是在 Windows 上,也许正斜杠会变成反斜杠,或者正斜杠是错字,应该改为反斜杠一。 我在 2015 年,我需要使用 ..\..\Packages 将其上移一个文件夹。 ../lib 这是正斜杠,不是反斜杠。你是什​​么意思? 是的,就是正斜杠。更新答案【参考方案5】:

发行说明中针对 2.1 提出的解决方案不能开箱即用。他们忘了提到有代码:

internal string ResolveInstallPath()

    if (!string.IsNullOrEmpty(this.OutputDirectory))
    
        return this.OutputDirectory;
    
    ISettings settings = this._configSettings;

    ...

这会阻止它工作。要解决此问题,您需要修改 NuGet.targets 文件并删除“OutputDirectory”参数:

    <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(RequireConsentSwitch)</RestoreCommand>

所以现在,如果您在 NuGet.config 中的某处添加“repositoryPath”配置(请参阅发行说明以了解放置配置文件的有效位置的描述),它会将所有包恢复到单个位置,但是...您的.csproj 仍然包含编写为相对路径的程序集的提示...

我仍然不明白他们为什么要努力而不是更改 PackageManager,以便添加相对于 PackagesDir 的提示路径。这就是我手动在本地(在我的桌面上)和构建代理上拥有不同包位置的方式。

<Reference Include="Autofac.Configuration, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
  <Private>True</Private>
  <HintPath>$(PackagesDir)\Autofac.2.6.3.862\lib\NET40\Autofac.Configuration.dll</HintPath>
</Reference>

【讨论】:

你是绝对正确的。在我的公司,我们实际上使用了我们自己修改的 NuGet 版本,它完全符合您的描述,即它添加了相对于 Packages Dir 的 HintPaths,而不是相对于项目文件的位置。这工作得很好。不幸的是,我们一直没有尝试将我们对 NuGet 所做的更改引入官方版本,但也许现在是时候这样做了...... @afrischke:如果你能做到,那就太好了。谢谢。知道什么时候会发生这种情况吗?【参考方案6】:

除了 Shane Kms 回答之外,如果您已激活 Nuget 包还原,您可以编辑位于 .nuget 文件夹中的 NuGet.config,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <repositoryPath>..\..\ExtLibs\Packages</repositoryPath>
</configuration>

注意额外的“..\”,因为它从 .nuget 文件夹而不是解决方案文件夹回溯。

【讨论】:

【参考方案7】:

要使用 PackageReference 而不是 packages.config 更改项目的路径,您需要使用 globalPackagesFolder

来自https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file

globalPackagesFolder(仅使用 PackageReference 的项目)

默认全局包文件夹的位置。默认是 %userprofile%.nuget\packages (Windows) 或 ~/.nuget/packages (Mac/Linux)。相对路径可用于特定项目 nuget.config 文件。此设置被 NUGET_PACKAGES 覆盖 环境变量,优先。

repositoryPath(仅限packages.config)

安装 NuGet 包的位置,而不是默认的 $(Solutiondir)/packages 文件夹。可以在项目特定的 nuget.config 中使用相对路径 文件。此设置被 NUGET_PACKAGES 环境覆盖 变量,优先。

<config>
    <add key="globalPackagesFolder" value="c:\packageReferences" />
    <add key="repositoryPath" value="c:\packagesConfig" />
</config>

我将 Nuget.config 放在我的解决方案文件旁边,它可以工作。

【讨论】:

【参考方案8】:

由于缺少一些提示,这些答案都不适合我(Nuget 2.8.6),将尝试在此处添加它们,因为它可能对其他人有用。

阅读以下来源后:https://docs.nuget.org/consume/NuGet-Config-Settingshttps://github.com/NuGet/Home/issues/1346 看来

    使用不同的安装包正确工作 repositoryPath 你需要使用 forward 斜杠,这是因为它们使用 Uri 对象来解析位置。 一开始没有 $,它仍然忽略我的设置。 NuGet 缓存配置文件,修改后需要重新加载解决方案/VS。 我在使用 NuGet.exe 命令设置此选项时也遇到了奇怪的问题,因为它修改了我在 AppData\Roaming\NuGet 下的全局 NuGet.exe 并开始在那里恢复包(因为该文件具有更高的优先级,只是猜测)。

例如

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
  <config>
    <add key="repositorypath" value="$/../../../Common/packages" />
  </config>
</configuration>

您还可以使用 NuGet 命令来确保语法正确,如下所示:

NuGet.exe config -Set repositoryPath=$/../../../Common/packages -ConfigFile NuGet.Config

【讨论】:

【参考方案9】:

对于 .NET Core 项目和 Visual Studio 2017,我能够通过提供以下配置将所有包恢复到相对路径:

<configuration>
  <config>
    <add key="globalPackagesFolder" value="lib" />
  </config>
  ... 
</configuration>

根据我的经验,无论 sln 文件在哪里,都会在找到 Nuget.config 的同一级别创建 lib 文件夹。 我测试了命令行 dotnet restore 和 Visual Studio 2017 重建的行为是相同的

【讨论】:

我试过这个。我将globalPackagesFolder 键设置为我项目的包文件夹。我试图用dotnet add package MyPackage 添加一个包。 nuget.exe 将 83 个 .NET 包的整个框架下载到该文件夹​​中。那不是我的本意。我只希望我的单个 MyPackage 在我的本地、源代码控制的包文件夹中。 不要那样做!这将很快使您的 HDD 不堪重负,因为每次创建新应用时都会下载整个框架包。 根据对另一个问题的回答:***.com/a/47407399/4572240“respositoryPath 用于 packages.config 项目,globalPackagesFolder 用于 PackageReference 项目”。【参考方案10】:

接受答案中的配置文件在 VS2012 中适用于我。 但是,对我而言,它在我执行以下操作时有效:

    在 VS 中创建一个新项目。 退出 VS - 这似乎很重要。 将配置文件复制到项目文件夹中。 重启 VS 并添加包。

如果我按照这些步骤操作,我可以使用共享包文件夹。

【讨论】:

重启 VS 是我让它工作的唯一方法。猜猜包管理器缓存了它。【参考方案11】:

我刚刚发现的另一个小消息。 (这可能非常基本,以至于有些人没有提到它,但这对我的解决方案很重要。)“packages”文件夹最终与您的 .sln 文件位于同一文件夹中。

我们移动了 .sln 文件,然后修复了里面的所有路径以找到各种项目,瞧!我们的 packages 文件夹最终位于我们想要的位置。

【讨论】:

【参考方案12】:

VS 2017 更新:

看起来 Nuget 团队的人们终于开始自己使用 Nuget,这帮助他们找到并修复了一些重要的事情。所以现在(如果我没记错的话,因为仍然没有迁移到 VS 2017)下面不再需要了。您应该能够将“repositoryPath”设置为本地文件夹,它会起作用。即使您可以完全保留它,因为默认情况下还原位置已从解决方案文件夹移出到机器级别。再说一遍——我还是没有自己测试过

VS 2015 及更早版本

只是对其他答案的提示(特别是this):

可以通过配置更改NuGet Package文件夹的位置,但VisualStudio仍然相对引用该文件夹中的程序集:

<HintPath>..\..\..\..\..\..\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

为了解决这个问题(直到找到更好的解决方案),我使用 subst 命令创建了一个虚拟驱动器,该驱动器指向 Packages 文件夹的新位置:

subst N: C:\Development\NuGet\Packages

现在添加新的 NuGet 包时,项目引用使用其绝对位置:

<HintPath>N:\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

注意:

    这样的虚拟驱动器重启后会被删除,所以一定要handle it 不要忘记替换项目文件中的现有引用。

【讨论】:

今天还是这样吗?我的意思是我们不能为新添加的软件包使用绝对位置?这个虚拟驱动器解决方案对我来说看起来很麻烦 是的,仍然没有任何变化 我实际上更喜欢相对路径 - 这样,如果不同的开发人员有不同的代码根位置,源代码控制就不会发生冲突。 我想知道为什么你不能使用&lt;HintPath&gt;$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll&lt;/HintPath&gt; 而不是使用subst 我希望所有包都在一个地方,而不是每个解决方案【参考方案13】:

最一致的方式是使用nuget config显式设置配置:

nuget config -set repositoryPath=c:\packages -configfile c:\my.config

https://docs.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior#changing-config-settings

【讨论】:

【参考方案14】:

仅使用 Nuget 2.8.3 进行更新。要更改已安装包的位置,我通过右键单击解决方案启用了包还原。编辑 NuGet.Config 并添加这些行:

  <config>
    <add key="repositorypath" value="..\Core\Packages" />
  </config>

然后重建解决方案,它将所有包下载到我想要的文件夹并自动更新引用。

【讨论】:

【参考方案15】:

Visual Studio 2019Nuget 5.9。*

    打开 %AppData%\NuGet 文件夹,打开现有的 NuGet.Config 文件。编辑 repositoryPath 键并设置新目标。
 <config>
  <add key="repositoryPath" value="D:\.nuget\packages" />
  </config>
    在环境变量中编辑系统变量 NUGET_PACKAGES 并设置新目标

    重启 VS。无需将 nuget.config 文件放入每个解决方案中。

【讨论】:

【参考方案16】:
    在解决方案文件所在的同一目录中创建nuget.config,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="packages" />
  </config>
</configuration>

'packages' 将是恢复所有包的文件夹。

    关闭 Visual Studio 解决方案并重新打开。

【讨论】:

它在 VS 2022 中有效吗?我已经设置了相同的配置,但它现在可以工作了。【参考方案17】:

如果您使用的是 Visual Studio 2019 和 NuGet 版本 4(或更高版本),您可以通过编辑 NuGet.config 文件来更改路径。

NuGet.config 文件位于 C:\Users%USER_NAME%\AppData\Roaming\NuGet

将“globalPackagesFolder”和“repositoryPath”键添加到配置文件中。设置您想要的值。

这是一个例子

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="Microsoft Visual Studio Offline Packages" value="C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\" />
  </packageSources>
  <config>
    <add key="globalPackagesFolder" value="E:\.packages" />
    <add key="repositoryPath" value="E:\.nuget" />
  </config>
</configuration>

【讨论】:

它在 VS 2022 中有效吗?我已经设置了相同的配置,但它现在可以工作了。

以上是关于是否可以更改 NuGet 包的位置?的主要内容,如果未能解决你的问题,请参考以下文章

用户空间中的 .nuget 文件夹

更改NuGet包位置文件夹

确保机密数据免受Nuget包的侵害

从命令行添加Nuget对VS项目包的引用

修改Nuget默认包存放位置

.NET 转到 NuGet 包的实现