对于外部和内部包源,在多个解决方案中引用的项目,我也有类似的情况。今天,我刚刚使用我们的一个代码库进行了这项工作,并且似乎正在使用开发人员工作站和构建服务器。下面的过程考虑了这种情况(尽管不难适应将通用包文件夹放在其他位置)。
- 程式库
- 项目A
- 项目B
- 项目C
- 解决方案
- 解决方案1
- 解决方案2
- 解决方案3
- 包(这是所有解决方案共享的通用包)
从Visual Studio 2015 Update 3的NuGet 3.5.0.1484开始更新的答案
现在,此过程比我最初解决此问题并认为是时候进行更新时要容易一些。通常,该过程是相同的,只是步骤更少。结果是解决或提供以下内容的过程:
- 解决方案中可见并跟踪需要提交给源代码控制的所有内容
- 在Visual Studio中使用“程序包管理器”安装新程序包或更新程序包将使用正确的存储库路径
- 初始配置后,不会对.csproj文件进行黑客攻击
- 无需修改开发人员工作站(签出时即可构建代码)
有一些潜在的缺点要注意(YMMV,我还没有经历过)。请参阅下面的Benol答案和评论。
添加NuGet.Config
您将要在\ Solutions \文件夹的根目录中创建一个NuGet.Config文件。确保这是您创建的UTF-8编码文件,如果不确定如何执行此操作,请使用Visual Studio的“文件”->“新建”->“文件”菜单,然后选择“ XML文件”模板。将以下内容添加到NuGet.Config中:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
对于repositoryPath设置,可以使用$令牌指定绝对路径或相对路径(推荐)。$令牌基于NuGet.Config的位置($令牌实际上是相对于NuGet.Config位置下方的一级)。因此,如果我有\ Solutions \ NuGet.Config并想要\ Solutions \ Packages,则需要指定$ \ .. \ Packages作为值。
接下来,您需要向解决方案中添加一个名为“ NuGet”的解决方案文件夹(在解决方案上单击鼠标右键,依次单击“添加”->“新解决方案文件夹”)。解决方案文件夹是仅存在于Visual Studio解决方案中的虚拟文件夹,不会在驱动器上创建实际的文件夹(您可以从任何地方引用文件)。右键单击“ NuGet”解决方案文件夹,然后单击“添加”->“现有项”,然后选择\ Solutions \ NuGet.Config。
我们这样做的原因是,使其在解决方案中可见,并应有助于确保将其正确提交给您的源代码控件。您可能要对参与共享项目的代码库中的每个解决方案执行此步骤。
通过将NuGet.Config文件放置在任何.sln文件上方的\ Solutions \中,我们利用了NuGet将从“当前工作目录”向上递归导航文件夹结构以查找要使用的NuGet.Config文件这一事实。这里的“当前工作目录”意味着几件不同的事情,一个是NuGet.exe的执行路径,另一个是.sln文件的位置。
切换包裹文件夹
首先,我强烈建议您浏览每个解决方案文件夹,并删除任何存在的\ Packages \文件夹(您需要先关闭Visual Studio)。这样可以更轻松地查看NuGet将新配置的\ Packages \文件夹放在何处,并确保指向错误的\ Packages \文件夹的任何链接都会失败,然后可以修复。
在Visual Studio中打开您的解决方案,然后开始“全部重建”。忽略您将收到的所有构建错误,这是目前所希望的。但是,这应该在构建过程开始时启动NuGet软件包还原功能。验证是否已在所需位置创建\ Solutions \ Packages \文件夹。如果还没有,请检查您的配置。
现在,对于解决方案中的每个项目,您将需要:
- 右键单击项目,然后选择“卸载项目”
- 右键单击项目,然后选择编辑your-xxx.csproj
- 查找对\ packages \的任何引用,并将其更新到新位置。
- 其中大多数将是<HintPath>引用,但不是全部。例如,WebGrease和Microsoft.Bcl.Build将具有需要更新的单独的路径设置。
- 保存.csproj,然后在项目上单击鼠标右键,然后选择“重新加载项目”
一旦所有.csproj文件都已更新,请启动另一个“全部重建”,您就不会再有关于缺少引用的构建错误。至此,您已完成工作,现在将NuGet配置为使用共享的Packages文件夹。
从VStudio 2012开始的NuGet 2.7.1(2.7.40906.75)
首先要记住的是nuget.config不能控制nuget软件包系统中的所有路径设置。弄清楚这一点特别令人困惑。具体来说,问题在于msbuild和Visual Studio(称为msbuild)不在nuget.config中使用路径,而是在nuget.targets文件中覆盖了该路径。
环境准备
首先,我将浏览解决方案的文件夹,并删除所有存在的\ packages \文件夹。这将有助于确保将所有软件包可见地安装到正确的文件夹中,并有助于发现整个解决方案中的任何错误路径引用。接下来,我将确保您安装了最新的nuget Visual Studio扩展。我还要确保您在每个解决方案中都安装了最新的nuget.exe。打开命令提示符,进入每个$(SolutionDir)\ .nuget \文件夹,然后执行以下命令:
nuget update -self
设置NuGet的通用软件包文件夹路径
打开每个$(SolutionDir)\ .nuget \ NuGet.Config,然后在<configuration>部分中添加以下内容:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
注意:您可以使用绝对路径或相对路径。请记住,如果您使用带有$的相对路径,则该路径相对于NuGet.Config位置下方的一个级别(请相信这是一个错误)。
设置MSBuild和Visual Studio的通用软件包文件夹路径
打开每个$(SolutionDir)\ .nuget \ NuGet.targets并修改以下部分(请注意,对于非Windows,下面还有另一部分):
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
<!-- Windows specific commands -->
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
<PackagesDir>$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
</PropertyGroup>
将PackagesDir更新为
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
注意: GetFullPath会将我们的相对路径解析为绝对路径。
将所有nuget软件包还原到公共文件夹
打开命令提示符并转到每个$(SolutionDir)\ .nuget并执行以下命令:
nuget restore ..\YourSolution.sln
此时,您应该在公共位置只有一个\ packages \文件夹,而在任何解决方案文件夹中都没有。如果没有,请验证您的路径。
修复项目参考
在文本编辑器中打开每个.csproj文件,找到对\ packages的所有引用,并将它们更新为正确的路径。其中大多数将是<HintPath>引用,但不是全部。例如,WebGrease和Microsoft.Bcl.Build将具有需要更新的单独的路径设置。
建立您的解决方案
在Visual Studio中打开解决方案,然后开始构建。如果它抱怨丢失的软件包需要还原,请不要以为该软件包丢失并且需要还原(错误可能会引起误解)。您的.csproj文件之一中的路径可能不正确。还原软件包之前,请先进行检查。
是否有关于缺少软件包的构建错误?
如果您已经验证了.csproj文件中的路径正确,则可以尝试两种方法。如果这是从源代码控制中更新代码的结果,则可以尝试签出干净副本,然后进行构建。这对我们的一名开发人员有效,我认为.suo文件中或类似的东西。另一个选择是使用相关解决方案的.nuget文件夹中的命令行手动强制软件包还原:
nuget restore ..\YourSolution.sln
$
在相对路径前面缺少。另外,关于NuGet.Config文件的问题的答案在这里。它首先在.nuget,然后在所有的父目录,然后在你的应用程序数据的“全球性”文件:时使它们以相反的顺序(无论该手段)。