.net NuGet 自动包还原不适用于 MSBuild

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22300375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:41:36  来源:igfitidea点击:

NuGet auto package restore does not work with MSBuild

.netbuildmsbuildnugetnuget-package-restore

提问by UserControl

I'm trying to build a solution with packagescontent missing (except repositories.configinside) with MSBuild 12.0. I expect it to auto restore all missing packages before building but this is not the case - MsBuild reports tons of errors:

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

"are you missing a using directive or an assembly reference?"

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

NuGet Manager is 2.7 (I see this in Visual Studio 2013 about box). I even tried to pass EnableNuGetPackageRestore=trueparameter - no luck. What am I missing?

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

采纳答案by KMoraz

UPDATED with latest official NuGet documentation as of v3.3.0

更新了最新的官方 NuGet 文档,从 v3.3.0 开始

Package Restore Approaches

包恢复方法

NuGet offers three approaches to using package restore.

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



Automatic Package Restoreis the NuGet team's recommended approach to Package Restore within Visual Studio, and it was introduced in NuGet 2.7. Beginning with NuGet 2.7, the NuGet Visual Studio extension integrates into Visual Studio's build events and restores missing packages when a build begins. This feature is enabled by default, but developers can opt out if desired.

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



Here's how it works:

  1. On project or solution build, Visual Studio raises an event that a build is beginning within the solution.
  2. NuGet responds to this event and checks for packages.config files included in the solution.
  3. For each packages.config file found, its packages are enumerated and Checked for exists in the solution's packages folder.
  4. Any missing packages are downloaded from the user's configured (and enabled) package sources, respecting the order of the package sources.
  5. As packages are downloaded, they are unzipped into the solution's packages folder.

这是它的工作原理:

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


If you have Nuget 2.7+ installed; it's important to pick one method for > managing Automatic Package Restore in Visual Studio.

Two methods are available:

  1. (Nuget 2.7+): Visual Studio -> Tools -> Package Manager -> Package Manager Settings -> Enable Automatic Package Restore
  2. (Nuget 2.6 and below) Right clicking on a solution and clicking "Enable Package Restore for this solution".

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

有两种方法可用:

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



Command-Line Package Restoreis required when building a solution from the command-line; it was introduced in early versions of NuGet, but was improved in NuGet 2.7.

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

nuget.exe restore contoso.sln


The MSBuild-integrated package restoreapproach is the original Package Restore implementation and though it continues to work in many scenarios, it does not cover the full set of scenarios addressed by the other two approaches.

MSBuild 集成的包还原方法是原始的包还原实现,虽然它在许多场景中继续工作,但它没有涵盖其他两种方法所解决的完整场景集。

回答by Ian Kemp

If you are using Visual Studio 2017 or later which ships with MSBuild 15 or later, and your .csproj files are in the new PackageReferenceformat, the simplest method is to use the new MSBuild Restoretarget.

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



No-one has actually answered the original question, which is "how do I get NuGet packages to auto-restore when building from the command-line with MSBuild?" The answer is: unless you are using the "Enable NuGet package restore" option (which is now deprecated as per this reference), you can't (but see below). If you are trying to do e.g. automated builds on a CI server, this sucks.

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

However there is a slightly roundabout way to get the desired behaviour:

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

  1. Download the latest NuGet executable from https://dist.nuget.org/win-x86-commandline/latest/nuget.exeand place it somewhere in your PATH. (You can do this as a pre-build step.)
  2. Run nuget restorewhich will auto-download all the missing packages.
  3. Run msbuildto build your solution.
  1. https://dist.nuget.org/win-x86-commandline/latest/nuget.exe下载最新的 NuGet 可执行文件并将其放在 PATH 中的某个位置。(您可以将此作为预构建步骤。)
  2. 运行nuget restore这将自动下载所有丢失的包。
  3. 运行msbuild以构建您的解决方案。

Aside: while the new and recommended way to do auto package restore involves less clutter in your version control, it also makes command-line package restore impossible unless you jump through the extra hoop of downloading and running nuget.exe. Progress?

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

回答by Owen Johnson

Nuget's Automatic Package Restore is a feature of the Visual Studio (starting in 2013), not MSBuild. You'll have to run nuget.exe restoreif you want to restore packages from the command line.

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

You can also use the Enable Nuget Package Restore feature, but this is no longer recommended by the nuget folks because it makes intrusive changes to the project files and may cause problems if you build those projects in another solution.

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

回答by Ying

It took me some time to figure out the whole picture and I'd like to share here.

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

Visual Studio has two approaches to use package restore: Automatic Package Restore and MSBuild-Integrated package restore. The 'MSBuild-Integrated Package Restore' restores packages DURING the building process that might cause issues in some scenarios. The 'Automatic Package Restore' is the recommended approachby the NuGet team.

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

There are several steps to to make 'Automatic Package Restore' work:

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

  1. In Visual Studio, Tools -> Extensions and Updates, Upgrade NuGet if there is a newer version (Version 2.7 or later)

  2. If you use TFS, in your solution's .nuget folder, remove the NuGet.exe and NuGet.targes files. Then edit NuGet.Config to not check in NuGet packages:

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

    If you checked in the solution's packages folder to TFS before, delete the folder and check in the deletion of package folder deletion.

    If you don't use TFS, delete the .nuget folder.

  3. In each project file (.csproj or .vbproj) in your solution, remove the line that references NuGet.targets file. The reference looks like this:

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

    Remove this line in every project file in your solution.

  4. In Visual Studio menu, either through

    Tools -> Options -> Package Manager -> General or Tools -> NuGet Package Manager -> Package Manager Settings

    please enable the following two options 1) 'Allow NuGet to download missing packages' 2) 'Automatically check for missing packages during build in Visual Studio'

  5. Test your package restore configuration by the following steps

    • Save your solution and close Visual Studio
    • Delete your solution's packages folder
    • Start Visual Studio, open your solution and rebuild it.
  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,打开您的解决方案并重建它。

回答by Chris

MSBuild 15 has a /t:restore optionthat does this. it comes with Visual Studio 2017.

MSBuild 15 有一个/t:restore 选项可以做到这一点。它带有 Visual Studio 2017。

If you want to use this, you also have to use the new PackageReference, which means replacing the packages.configfile with elements like this (do this in *.csproj):

如果你想使用它,你还必须使用新的PackageReference,这意味着用这样的packages.config元素替换文件(在 *.csproj 中执行此操作):

<ItemGroup>
  <!-- ... -->
  <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
  <!-- ... -->
</ItemGroup>

There is an automated migration to this format if you right click on 'References' (it might not show up if you just opened visual studio, rebuild or open up the 'Manage NuGet packages for solution' window and it will start appearing).

如果您右键单击“引用”,则会自动迁移到此格式(如果您只是打开 Visual Studio、重建或打开“管理 NuGet 解决方案包”窗口,它可能不会显示,它会开始出现)。

回答by Fetchez la vache

Ian Kemp has the answer (have some points btw..), this is to simply add some meat to one of his steps.

伊恩坎普有答案(顺便说一句,有一些观点......),这只是在他的一个步骤中添加一些肉。

The reason I ended up here was that dev's machines were building fine, but the build server simply wasn't pulling down the packages required (empty packages folder) and therefore the build was failing. Logging onto the build server and manually building the solution worked, however.

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

To fulfil the second of Ians 3 point steps (running nuget restore), you can create an MSBuild target running the exec command to run the nuget restore command, as below (in this case nuget.exe is in the .nuget folder, rather than on the path), which can then be run in a TeamCity build step (other CI available...) immediately prior to building the solution

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

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

For the record I'd already tried the "nuget installer" runner type but this step was hanging on web projects (worked for DLL's and Windows projects)

作为记录,我已经尝试过“nuget installer”运行程序类型,但是这一步挂在 web 项目上(适用于 DLL 和 Windows 项目)

回答by Dejan

Note that if you are using TeamCityas a build server, you get a "NuGet Installer" step that you can use to restore all the packages before the build step.

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

回答by fabriciorissetto

Sometimes this occurs when you have the folder of the package you are trying to restore inside the "packages" folder (i.e. "Packages/EntityFramework.6.0.0/") but the "DLLs" are not inside it(most of the version control systems automatically ignore ".dll" files). This occurs because before NuGet tries to restore each package it checks if the folders already exist, so if it exists, NuGet assumes that the "dll" is inside it. So if this is the problem for you just delete the folder that NuGet will restore it correctly.

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

回答by Sumeshk

There is a packages.configfile with the project, it contains the package details.

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

Also there is a .nuget folder which contains the NuGet.exe and NuGet.targets. if any one of the file is missing it will not restore the missing package and cause "are you missing a using directive or an assembly reference?" error

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

回答by David

In Visual Studio 2017 - When you compile using IDE - It will download all the missing nuget packages and save in the folder "packages".

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

But on the build machine compilation was done using msbuild.exe. In that case, I downloaded nuget.exe and kept in path.

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

During each build process before executing msbuild.exe. It will execute -> nuget.exe restore NAME_OF_SLN_File (if there is only one .SLN file then you can ignore that parameter)

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