Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vs2017: NuGet packages not restored with MSBuild

  1. I build from VS2017 and the packages are downloaded and the projects build.
  2. Then I nuke the packages folder.
  3. Then I build using MSBuild the projects fail because the packages don't exist, they haven't been restored.

I have "download missing packages" on

The project files would have been originally created in VS 2013

The build.proj using the MSBuild task to build the solution.

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

My google-fu has failed me, any and all ideas will be greatfully received.

like image 892
Binary Worrier Avatar asked Jan 22 '18 17:01

Binary Worrier


People also ask

Does MSBuild restore NuGet packages?

Restore using MSBuild This command is available only in NuGet 4. x+ and MSBuild 15.1+, which are included with Visual Studio 2017 and higher versions. Starting with MSBuild 16.5+, this command can also restore packages. config based projects when run with -p:RestorePackagesConfig=true .

How do I fix a NuGet package error?

Quick solution for Visual Studio usersSelect the Tools > NuGet Package Manager > Package Manager Settings menu command. Set both options under Package Restore. Select OK. Build your project again.

How do I force a NuGet package to reinstall?

Switch to the Browse tab, search for the package name, select it, then select Install). For all packages, delete the package folder, then run nuget install . For a single package, delete the package folder and use nuget install <id> to reinstall the same one.


1 Answers

packages.config based projects need to be restored via NuGet, not MSBuild. Visual Studio does this when requesting a build via VS. If you need to do it from command line, you need to use the command line nuget.exe utility to restore the packages.

Only the PackageReference way of referencing NuGet packages is integrated into MSBuild. You can switch to this format by uninstalling all NuGet packages from the project, and changing the default package management format or select the "Allow format selection on first package install" checkbox. Then you can re-add the packages (only top-level packages are needed) and make sure it does not generate a packages.config file.

There's a few issues here:

  1. After a restore, MSBuild has to re-evaluate the project file. When using the <MSBuild> task inside a CI script, this only happens when a different set of properties are passed to the task. This is because the Restore generates auto-imported files in the obj\ directory that are checked for during the evaluation.

  2. Should the restore not generate, but alter these files, this is not enough and the project has to be re-evaluated with clean xml caches. This is not possible with the <MSBuild> task. MSBuild 15.5 has introduces a /restore option to execute a Restore target, then clean these caches (for which there was no API before) and execute the rest of the build as requested. Before 15.5, two separate invocations of msbuild.exe were needed to ensure that incremental restore+builds produce the correct output.

If you want to use a CI build project with PackageReference, the safest way is to create a build.proj that has a restore and a build target:

<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>

And execute it using

msbuild /restore /t:Build build.proj
like image 145
Martin Ullrich Avatar answered Jan 01 '23 21:01

Martin Ullrich