Vs2017:未使用 MSBuild 还原 NuGet 包

Vs2017: NuGet packages not restored with MSBuild

  1. 我从 VS2017 构建并下载包和项目 建造。
  2. 然后我核对包文件夹。
  3. 然后我使用 MSBuild 构建项目失败,因为包没有 存在,但尚未恢复。

我有 "download missing packages"

项目文件最初是在 VS 2013 中创建的

build.proj 使用 MSBuild 任务构建解决方案。

<MSBuild Projects ="$(root)\src\MySolution.sln" ContinueOnError ="false" Properties="Configuration=$(Configuration)">
    <Output ItemName="OutputFiles" TaskParameter="TargetOutputs"/>
</MSBuild>

我的 google-fu 让我失望了,任何和所有的想法都会被很好地接受。

我还 运行 解决了 MSBuild 未拉包的问题。我使用 RestoreConfigFile 添加路径 nuget.config 文件到属性参数

RestoreConfigFile=$(MSBuildStartupDirectory)\.nuget\nuget.config

并且还更改了 MSBuild 任务上的 Targets 值:

MSBuild Targets="Restore;Clean;Build" Projects=...

Restore 目标实际上强制拉取了软件包,RestoreConfigFile 将其指向我的设置。

packages.config 基于项目需要通过 NuGet 恢复,而不是 MSBuild。 Visual Studio 在通过 VS 请求构建时执行此操作。如果您需要从命令行执行此操作,则需要使用命令行 nuget.exe 实用程序来恢复包。

只有 PackageReference 引用 NuGet 包的方式集成到 MSBuild 中。您可以通过从项目中卸载所有 NuGet 包并更改默认包管理格式或 select "Allow format selection on first package install" 复选框来切换到此格式。然后你可以重新添加包(只需要顶级包)并确保它不会生成 packages.config 文件。

这里有几个问题:

  1. 还原后,MSBuild 必须重新评估项目文件。在 CI 脚本中使用 <MSBuild> 任务时,只有在将一组不同的属性传递给任务时才会发生这种情况。这是因为还原会在评估期间检查的 obj\ 目录中生成自动导入的文件。

  2. 如果恢复不生成,而是更改这些文件,这还不够,必须使用干净的 xml 缓存重新评估项目。 <MSBuild> 任务无法做到这一点。 MSBuild 15.5 引入了一个 /restore 选项来执行 Restore 目标,然后清理这些缓存(之前没有 API)并按要求执行构建的其余部分。在 15.5 之前,需要两次单独调用 msbuild.exe 以确保增量还原+构建产生正确的输出。

如果您想将 CI 构建项目与 PackageReference 一起使用,最安全的方法是创建具有恢复和构建目标的 build.proj

<Project>
  <Target Name="Restore">
    <MSBuild Projects="$(root)\src\MySolution.sln" Targets="Restore" />
  </Target>
  <Target Name="Build">
    <MSBuild Projects="$(root)\src\MySolution.sln" Targets="Build" />
  </Target>
</Project>

并使用

执行
msbuild /restore /t:Build build.proj

我发现调用 nuget restore MySolution.sln 会恢复解决方案的包。

我将 nuget.exe 放在我的构建文件夹中,运行 恢复我源代码树中的每个解决方案。

我的 MsBuild 目标是恢复所有解决方案中所有项目的包。

<Target Name="NuGetRestore">
  <ItemGroup>
    <slns Include="$(MSBuildProjectDirectory)\..\**\*.sln"/>
  </ItemGroup>
  <Exec Command="$(MSBuildProjectDirectory)\nuget restore %(slns.Identity)"/>
</Target>

Nuget.exe不必在每个项目文件夹中,只需在带有build的文件夹中即可。