121

我正在尝试使用 MSBuild 12.0构建一个packages缺少内容(内部除外)的解决方案。repositories.config我希望它在构建之前自动恢复所有丢失的包,但事实并非如此——MsBuild 报告了大量错误:

“您是否缺少 using 指令或程序集引用?”

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

4

12 回答 12

247

如果您使用的是 MSBuild 15 或更高版本附带的 Visual Studio 2017 或更高版本,并且您的 .csproj 文件采用PackageReference格式,最简单的方法是使用新的 MSBuildRestore目标


没有人真正回答过最初的问题,即“在使用 MSBuild 从命令行构建时,如何让 NuGet 包自动恢复?” 答案是:除非您使用“启用 NuGet 包还原”选项(现在根据此参考已弃用),否则您不能(但请参见下文)。如果您尝试在 CI 服务器上进行自动化构建,这很糟糕。

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

  1. 从https://dist.nuget.org/win-x86-commandline/latest/nuget.exe下载最新的 NuGet 可执行文件,并将其放在 PATH 中的某个位置。(您可以将此作为预构建步骤。)
  2. 运行nuget restore它将自动下载所有丢失的包。
  3. 运行msbuild以构建您的解决方案。

顺便说一句:虽然新的和推荐的自动包恢复方法在您的版本控制中减少了混乱,但它也使命令行包恢复不可能,除非您跳过额外的下载和运行环节nuget.exe。进步?

于 2014-05-29T14:32:49.160 回答
56

Nuget 的自动包还原是 Visual Studio 的一项功能(从 2013 年开始),而不是 MSBuild。nuget.exe restore如果你想从命令行恢复包,你必须运行。

您还可以使用启用 Nuget 包还原功能,但 nuget 人员不再推荐此功能,因为它会对项目文件进行侵入性更改,并且如果您在另一个解决方案中构建这些项目可能会导致问题。

于 2014-04-10T18:03:25.863 回答
39

使用最新的官方 NuGet 文档更新 v3.3.0

包恢复方法

NuGet 提供了三种使用包还原的方法。


自动包还原是 NuGet 团队推荐的在 Visual Studio 中进行包还原的方法,它是在 NuGet 2.7 中引入的。从 NuGet 2.7 开始,NuGet Visual Studio 扩展集成到 Visual Studio 的生成事件中,并在生成开始时恢复丢失的包。默认情况下启用此功能,但如果需要,开发人员可以选择退出。


以下是它的工作原理:

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

如果您安装了 Nuget 2.7+;选择一种方法来管理 Visual Studio 中的自动包还原非常重要。

有两种方法可用:

  1. (Nuget 2.7+):Visual Studio -> 工具 -> 包管理器 -> 包管理器设置 -> 启用自动包还原
  2. (Nuget 2.6 及更低版本)右键单击解决方案并单击“为此解决方案启用包还原”。


从命令行构建解决方案时需要命令行包还原;它是在 NuGet 的早期版本中引入的,但在 NuGet 2.7 中得到了改进。

nuget.exe restore contoso.sln

MSBuild 集成的包还原 方法是原始的包还原实现,尽管它在许多场景中继续有效,但它并未涵盖其他两种方法解决的全部场景。

于 2014-03-10T14:17:39.610 回答
17

我花了一些时间才弄清楚整个画面,我想在这里分享。

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

有几个步骤可以使“自动包还原”工作:

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

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

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

    如果您之前将解决方案的包文件夹签入到 TFS,请删除该文件夹并签入包文件夹删除的删除。

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

  3. 在解决方案中的每个项目文件(.csproj 或 .vbproj)中,删除引用 NuGet.targets 文件的行。参考如下所示:

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

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

  4. 在 Visual Studio 菜单中,通过

    工具 -> 选项 -> 包管理器 -> 常规或工具 -> NuGet 包管理器 -> 包管理器设置

    请启用以下两个选项 1) '允许 NuGet 下载丢失的包' 2) '在 Visual Studio 中构建期间自动检查丢失的包'

  5. 通过以下步骤测试您的包还原配置

    • 保存解决方案并关闭 Visual Studio
    • 删除解决方案的包文件夹
    • 启动 Visual Studio,打开您的解决方案并重新构建它。
于 2014-03-10T17:13:28.507 回答
6

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 包以获取解决方案”窗口,它可能不会显示,它将开始出现)。

于 2018-05-30T15:56:12.390 回答
4

请注意,如果您使用TeamCity作为构建服务器,您将获得一个“NuGet 安装程序”步骤,您可以使用该步骤在构建步骤之前恢复所有包。

于 2015-07-06T13:01:17.137 回答
4

伊恩坎普有答案(顺便说一句……),这就是在他的一个步骤中简单地添加一些肉。

我最终来到这里的原因是开发人员的机器构建良好,但构建服务器根本没有拉下所需的包(空包文件夹),因此构建失败。但是,登录到构建服务器并手动构建解决方案是可行的。

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

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

作为记录,我已经尝试过“nuget 安装程序”运行器类型,但此步骤挂在 Web 项目上(适用于 DLL 和 Windows 项目)

于 2016-04-13T08:48:42.530 回答
2

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

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

于 2014-03-10T12:51:13.130 回答
2

有时,当您在“packages”文件夹(即“Packages/EntityFramework.6.0.0/”)中有要恢复的包的文件夹但“DLL”不在其中(大多数版本控制系统会自动忽略“.dll”文件)。发生这种情况是因为在 NuGet 尝试还原每个包之前,它会检查文件夹是否已存在,因此如果存在,NuGet 会假定“dll”在其中。因此,如果这是您的问题,只需删除 NuGet 将正确恢复它的文件夹。

于 2015-09-03T17:30:47.510 回答
1

我遇到了一个问题,即使用 devenv.exe 构建 sln 文件的脚本化夜间构建中未包含 nuget 包。

我遵循了Microsoft 的建议,关键步骤是更新 NuGet 配置%AppData%/NuGet,使其包含:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
于 2018-06-08T08:54:20.737 回答
0

在 Visual Studio 2017 中 - 当您使用 IDE 编译时 - 它将下载所有缺少的 nuget 包并保存在“包”文件夹中。

但是在构建机器上编译是使用 msbuild.exe 完成的。在这种情况下,我下载了 nuget.exe 并保存在路径中。

在执行 msbuild.exe 之前的每个构建过程中。它将执行 -> nuget.exe restore NAME_OF_SLN_File (如果只有一个 .SLN 文件,则可以忽略该参数)

于 2018-03-27T16:06:59.923 回答
-1

你也可以使用

Update-Package -reinstall

在 Visual Studio 的包管理控制台上还原 NuGet 包。

于 2019-05-02T11:06:58.753 回答