NuGet自动包恢复不适用于MSBuild

我想用MSBuild 12.0构build一个packages内容丢失的解决scheme(里面除了repositories.config )。 我希望它可以在构build之前自动恢复所有丢失的包,但事实并非如此 – MsBuild报告了大量的错误:

“你是否缺less使用指令或程序集引用?”

NuGet Manager是2.7(我在Visual Studio 2013中看到这个关于框)。 我什至试图传递EnableNuGetPackageRestore=true参数 – 没有运气。 我错过了什么?

使用v3.3.0以来的最新官方NuGet文档进行了更新

软件包还原方法

NuGet提供了三种使用软件包恢复的方法 。


自动软件包还原是NuGet团队推荐的在Visual Studio中进行软件包还原的方法,它在NuGet 2.7中引入。 从NuGet 2.7开始,NuGet Visual Studio扩展集成到Visual Studio的构build事件中,并在构build开始时恢复丢失的包。 此function默认启用,但开发人员可以根据需要select退出。


这是如何工作的:

  1. 在项目或解决scheme构build上,Visual Studio会在解决scheme中引发构build开始的事件。
  2. NuGet响应此事件并检查解决scheme中包含的packages.config文件。
  3. 对于find的每个packages.config文件,将其枚举枚举并且检查是否存在于解决scheme的packages文件夹中。
  4. 任何丢失的包都从用户的configuration(和启用)包源下载,尊重包源的顺序。
  5. 当软件包被下载时,它们被解压缩到解决scheme的软件包文件夹中。

如果你已经安装了Nuget 2.7+, select一种方法来pipe理Visual Studio中的自动包还原是非常重要的。

有两种方法可用:

  1. (Nuget 2.7+):Visual Studio – >工具 – >软件包pipe理器 – >软件包pipe理器设置 – >启用自动软件包还原
  2. (Nuget 2.6及以下版本)右键点击一个解决scheme,然后点击“为此解决scheme启用软件包恢复”。


从命令行构build解决scheme时, 命令行程序包还原是必需的; 它是在早期版本的NuGet中引入的,但是在NuGet 2.7中得到了改进。

 nuget.exe restore contoso.sln 

MSBuild集成软件包还原方法是最初的软件包还原实现,虽然它在许多情况下仍然可以工作,但并未涵盖其他两种方法所解决的全部情况。

没有人真的回答了原来的问题,即“如何从MSBuild命令行构build时如何获得NuGet包自动还原?” 答案是:除非你正在使用“启用NuGet包恢复”选项(现在已经根据这个参考不推荐使用),否则你不能(见下文)。 如果你正在尝试在CI服务器上自动构build,这很糟糕。

但是,有一个稍微迂回的方式来获得所需的行为:

  1. https://dist.nuget.org/win-x86-commandline/latest/nuget.exe下载最新的NuGet可执行文件,并将其放置在PATH的某处。; (您可以将其作为预构build步骤来完成。)
  2. 运行nuget restore将自动下载所有缺less的软件包。
  3. 运行msbuild来build立你的解决scheme。

另外:虽然新的和推荐的方式来做自动包还原包括在您的版本控制更less的混乱,它也使命令行包恢复不可能,除非你跳过额外的下载和运行nuget.exe 。 进展?

Nuget的自动包还原是Visual Studio(从2013年开始)的function,而不是MSBuild。 如果要从命令行恢复软件包,则必须运行nuget.exe restore

您也可以使用启用Nuget包恢复function,但这不再由nuget人推荐,因为它会对项目文件进行干扰性的更改,并且如果在另一个解决scheme中构build这些项目,可能会导致问题。

花了我一些时间来弄清楚整个情况,我想在这里分享一下。

Visual Studio有两种使用程序包还原的方法:自动程序包还原和MSBuild-集成程序包还原。 “MSBuild集成软件包还原”在构build过程中恢复软件包,在某些情况下可能会导致问题。 NuGet团队推荐的方法是“自动恢复包装”。

有几个步骤来使“自动包恢复”工作:

  1. 在Visual Studio中,工具 – >扩展和更新,如果有更新的版本(版本2.7或更高版本)升级NuGet,

  2. 如果您使用TFS,在您的解决scheme的.nuget文件夹中,删除NuGet.exe和NuGet.targes文件。 然后编辑NuGet.Config不检入NuGet包:

     <configuration> <solution> <add key="disableSourceControlIntegration" value="true" /> </solution> </configuration> 

    如果您之前将解决scheme的包文件夹签入了TFS,请删除该文件夹并检查删除包文件夹的删除。

    如果您不使用TFS,请删除.nuget文件夹。

  3. 在解决scheme中的每个项目文件(.csproj或.vbproj)中,删除引用NuGet.targets文件的行。 参考看起来像这样:

     <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> 

    在解决scheme中的每个项目文件中删除此行。

  4. 在Visual Studio菜单中,通过

    工具 – >选项 – >软件包pipe理器 – >常规或工具 – > NuGet软件包pipe理器 – >软件包pipe理器设置

    请启用以下两个选项1)'允许NuGet下载缺less的软件包'2)'在Visual Studio中生成时自动检查丢失的软件包'

  5. 通过以下步骤testing您的软件包恢复configuration

    • 保存您的解决scheme并closuresVisual Studio
    • 删除您的解决scheme的包文件夹
    • 启动Visual Studio,打开您的解决scheme并重build它。

Ian Kemp有答案(有点btw ..),这是简单地添加一些肉到他的一个步骤。

我在这里结束的原因是开发的机器正在build设,但生成服务器只是没有拉下所需的包(空包文件夹),因此构build失败。 然而,login到构build服务器并手动构build解决scheme。

要完成第二个Ians 3个步骤(运行nuget restore ),可以创build一个运行exec命令的MSBuild目标来运行nuget restore命令,如下所示(在这种情况下,nuget.exe位于.nuget文件夹中,而不是在path上),然后可以在构build解决scheme之前立即在TeamCity构build步骤(可用的其他CI)中运行

 <Target Name="BeforeBuild"> <Exec Command="..\.nuget\nuget restore ..\MySolution.sln"/> </Target> 

对于logging,我已经尝试了“nuget安装程序”跑步者types,但这一步挂在networking项目(工作的DLL和Windows项目)

该项目有一个packages.config文件,它包含软件包的详细信息。

还有一个包含NuGet.exe和NuGet.targets的.nuget文件夹。 如果任何一个文件丢失,将不会恢复丢失的包,并导致“你是否缺less使用指令或程序集引用? 错误

请注意,如果您使用TeamCity作为构build服务器,则会获得一个“NuGet安装程序”步骤,您可以使用该步骤在构build步骤之前还原所有的包。

有时候,当你在“packages”文件夹里面想要恢复的软件包文件夹(即“Packages / EntityFramework.6.0.0 /” ), 但是“DLLs”不在里面时 (大部分的版本控制系统自动忽略“.dll”文件)。 发生这种情况是因为在NuGet尝试恢复每个包之前,它检查文件夹是否已经存在,所以如果它存在,NuGet会假定“dll”在里面。 所以,如果这是你的问题只是删除NuGet将正确恢复它的文件夹。