我正在尝试使用MSBuild 12.0 构建一个packages
缺少内容(repositories.config
内部除外)的解决方案。我希望它可以在构建之前自动还原所有丢失的软件包,但事实并非如此-MsBuild报告大量错误:
“您是否缺少using指令或程序集引用?”
NuGet Manager是2.7(我在Visual Studio 2013中看到此对话框)。我什至试图传递EnableNuGetPackageRestore=true
参数-不走运。我想念什么?
我正在尝试使用MSBuild 12.0 构建一个packages
缺少内容(repositories.config
内部除外)的解决方案。我希望它可以在构建之前自动还原所有丢失的软件包,但事实并非如此-MsBuild报告大量错误:
“您是否缺少using指令或程序集引用?”
NuGet Manager是2.7(我在Visual Studio 2013中看到此对话框)。我什至试图传递EnableNuGetPackageRestore=true
参数-不走运。我想念什么?
Answers:
从v3.3.0开始,使用最新的官方NuGet文档进行了更新
NuGet提供了三种使用软件包还原的方法。
自动打包还原是NuGet团队推荐的在Visual Studio中进行打包还原的方法,它是在NuGet 2.7中引入的。从NuGet 2.7开始,NuGet Visual Studio扩展集成到Visual Studio的生成事件中,并在生成开始时恢复丢失的包。默认情况下启用此功能,但是如果需要,开发人员可以选择退出。
运作方式如下:
- 在项目或解决方案构建中,Visual Studio引发一个事件,表明在解决方案中开始构建。
- NuGet响应此事件,并检查解决方案中包含的packages.config文件。
- 对于找到的每个packages.config文件,将枚举其软件包,并在解决方案的packages文件夹中检查其是否存在。
- 所有丢失的软件包都是从用户已配置(并启用)的软件包源中下载的,并遵守软件包源的顺序。
- 下载软件包后,它们将解压缩到解决方案的packages文件夹中。
如果您已安装Nuget 2.7+;请务必选择一种方法>在Visual Studio中管理自动程序包还原。
有两种方法可用:
- (Nuget 2.7+):Visual Studio->工具->程序包管理器->程序包管理器设置->启用自动程序包还原
- (Nuget 2.6及更低版本)右键单击解决方案,然后单击“为此解决方案启用程序包还原”。
从命令行构建解决方案时,需要进行命令行程序包还原。它是在NuGet的早期版本中引入的,但在NuGet 2.7中得到了改进。
nuget.exe restore contoso.sln
MSBuild集成的程序包还原 方法是原始的程序包还原实现,尽管它在许多情况下仍可以使用,但它不涵盖其他两种方法所解决的全部方案。
如果您使用的是Visual Studio 2017或更高版本(随MSBuild 15或更高版本一起提供),并且.csproj文件为新PackageReference
格式,则最简单的方法是使用新的MSBuild Restore
目标。
没有人真正回答过最初的问题,即“使用MSBuild从命令行进行构建时,如何使NuGet软件包自动还原?” 答案是:除非您使用“ Enable NuGet package restore”(启用NuGet软件包还原)选项(此参考文献现已弃用)),否则不能这样做(但请参见下文)。如果您尝试在CI服务器上进行自动构建,那么很麻烦。
但是,有一种稍微回旋的方式来获得所需的行为:
nuget restore
将自动下载所有缺少的软件包。msbuild
以构建您的解决方案。顺便说一句:尽管新的推荐的自动软件包还原方法在您的版本控制中减少了混乱,但也使命令行软件包还原成为不可能,除非您跳过了下载和运行的额外工作nuget.exe
。进展?
nuget.exe
在/ trunk / ext中)。前进了一步-后退了两步:(
Nuget的自动软件包还原是Visual Studio(从2013年开始)的功能,而不是MSBuild的功能。nuget.exe restore
如果要从命令行还原软件包,则必须运行。
您也可以使用“启用Nuget软件包还原”功能,但是nuget不再推荐这样做,因为它对项目文件进行了侵入性更改,如果在其他解决方案中构建这些项目,则可能会导致问题。
我花了一些时间弄清楚整个图片,我想在这里分享。
Visual Studio有两种使用包还原的方法:自动包还原和MSBuild集成包还原。“ MSBuild集成软件包还原”在构建过程中还原在某些情况下可能引起问题的软件包。NuGet团队建议使用“自动打包还原” 方法。
要使“自动打包还原”工作,需要执行几个步骤:
在Visual Studio中的“工具”->“扩展和更新”中,如果有较新版本(2.7或更高版本),请升级NuGet。
如果使用TFS,请在解决方案的.nuget文件夹中,删除NuGet.exe和NuGet.targes文件。然后编辑NuGet.Config以不检入NuGet软件包:
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
</configuration>
如果您之前将解决方案的packages文件夹签入到TFS,请删除该文件夹并签入删除的package文件夹。
如果不使用TFS,请删除.nuget文件夹。
在解决方案中的每个项目文件(.csproj或.vbproj)中,删除引用NuGet.targets文件的行。参考看起来像这样:
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
在解决方案中的每个项目文件中删除此行。
在Visual Studio菜单中,通过
工具->选项->软件包管理器->常规或工具-> NuGet软件包管理器->软件包管理器设置
请启用以下两个选项1)'允许NuGet下载缺少的软件包'2)'在Visual Studio中构建期间自动检查缺少的软件包'
通过以下步骤测试程序包还原配置
MSBuild 15具有执行此操作的/ t:restore选项。它随Visual Studio 2017一起提供。
如果要使用它,则还必须使用新的PackageReference,这意味着用这样的packages.config
元素替换文件(在* .csproj中执行此操作):
<ItemGroup>
<!-- ... -->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
<!-- ... -->
</ItemGroup>
如果右键单击“参考”,则会自动迁移到此格式(如果您只是打开Visual Studio,重建或打开“为解决方案管理NuGet程序包”窗口,它可能不会显示,它将开始出现)。
伊恩·坎普(Ian Kemp)有答案(顺便说一句。),这只是在他的步骤之一中添加一些肉。
我在这里结束的原因是开发人员的机器运行良好,但是构建服务器根本没有拉低所需的软件包(空软件包文件夹),因此构建失败。但是,登录到构建服务器并手动构建解决方案是可行的。
要完成Ians 3点步骤中的第二步(运行nuget restore),您可以创建一个运行exec命令以运行nuget restore命令的MSBuild目标,如下所示(在这种情况下,nuget.exe在.nuget文件夹中,而不是在路径上),然后可以在构建解决方案之前立即在TeamCity构建步骤(可以使用其他CI ...)中运行
<Target Name="BeforeBuild">
<Exec Command="..\.nuget\nuget restore ..\MySolution.sln"/>
</Target>
作为记录,我已经尝试过“ nuget安装程序”运行程序类型,但是此步骤挂在了Web项目上(适用于DLL和Windows项目)
该项目有一个packages.config文件,其中包含软件包的详细信息。
还有一个.nuget文件夹,其中包含NuGet.exe和NuGet.targets。如果缺少任何一个文件,它将不会恢复丢失的软件包,并导致“您是否丢失了using指令或程序集引用?” 错误
.nuget
文件夹,从来没有。packages.config
项目文件夹中的所有文件都就位。
有时,当您在“ packages”文件夹中拥有要还原的软件包的文件夹(即“ Packages / EntityFramework.6.0.0 /”)但“ DLL”不在其中时(大多数版本控制),就会发生这种情况系统会自动忽略“ .dll”文件)。发生这种情况的原因是,在NuGet尝试还原每个软件包之前,它会检查文件夹是否已存在,因此如果文件夹已存在,则NuGet会假定其中存在“ dll”。因此,如果这是您的问题,只需删除NuGet即可正确还原该文件夹的文件夹。
我遇到了一个问题,即在使用devenv.exe构建sln文件的脚本化每晚构建中未包含nuget软件包。
我遵循了Microsoft的建议,关键步骤是更新其中的NuGet配置%AppData%/NuGet
,使其包含:
<configuration>
<packageRestore>
<add key="automatic" value="True" />
</packageRestore>
</configuration>