NuGet auto package restore does not work with MSBuild
Asked Answered
G

12

123

I'm trying to build a solution with packages content missing (except repositories.config inside) 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:

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

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

Glassy answered 10/3, 2014 at 12:39 Comment(3)
Are you building the solution within Visual Studio? Also is everything ticked in the Package Manager Settings in the Package Restore section? You do not need the .nuget folder if you are building within Visual Studio and using NuGet 2.7 or above.Steinberg
No, I'm using latest MsBuild (msdn.microsoft.com/en-us/library/hh162058.aspx) version from command line. Updated Nuget from within VS to 2.8 - no luck.Glassy
MSBuild alone won't restore and the VS addin either. You need to enable package restore as @KMoraz said, and then as Sumeshk said the .nuget folder appears and packages can be restored. Make sure you check .nuget in to source control.Compression
T
40

UPDATED with latest official NuGet documentation as of v3.3.0

Package Restore Approaches

NuGet offers three approaches to using package restore.


Automatic Package Restore is 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.


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.

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


Command-Line Package Restore is 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.exe restore contoso.sln

The MSBuild-integrated package restore approach 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.

Translucent answered 10/3, 2014 at 14:17 Comment(6)
This is no longer recommended by nuget. See the docs. docs.nuget.org/docs/workflows/…Crumpton
@OwenJohnson, that doc isn't dated that I can see and I don't see how it says it is not recommended now? I'm on VS2013 and that button appears to work fine. I did not have the problem referenced, "So, you clicked "Enable Nuget Package Restore" and now your stuff doesn't build. The steps to fix it are painful, but less painful with this script. " github.com/owen2/AutomaticPackageRestoreMigrationScript Perhaps there is another doc that explains this further.Graver
Automatic package restore replaces the ms-build integrated restore. The document is the instructions on how to upgrade. If you aren't having problems with the msbuild-integrated method, you don't need to do anything. In the simplest cases, it works, but if you have CI servers, shared project references, or some other conditions, you might step on some nasty landmines and have incorrect hintpaths or other issues.Crumpton
Using this answer AND the doing the "remove old stuff" instructions"Performing the migration" at docs.nuget.org/consume/package-restore/… , I was able to find success.Devol
Looks like things have changed again with NuGet 4 and .net standard.Crumpton
dotnet run worked for me learn.microsoft.com/en-us/nuget/consume-packages/…Centigram
F
250

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


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.

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.exe and place it somewhere in your PATH. (You can do this as a pre-build step.)
  2. Run nuget.exe restore which will auto-download all the missing packages.
  3. Run msbuild to build your solution.

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?

Filamentary answered 29/5, 2014 at 14:32 Comment(12)
Ended up with similar solution (but placed nuget.exe to /trunk/ext). One step forward - two steps back :(Glassy
This should be a correct anwer, not the one marked.Sarabia
This really does seem to be a little counter intuitive when it comes down to it, but you really do get more functionalities to add specific nuget packages back by using the command line. This solution worked for me while the auto restore failed.Chagall
I was using Jenkins and had to do this, it was a simple build step before calling msbuild - Windows batch file was the build step type and: cmd.exe /c "C:\Program Files\nuget\nuget.exe" restore <RelativePathToSln>.sln - I did the path to SLN as a habit / procedure just in case it didn't find sln file.Decanal
This approach worked for me when setting up a restore on a Jenkins build. One important key for me was that the NuGet.Config had to be in the same directory as my .SLN file. No combination of other config file locations, including specifying -ConfigFile on the command line would work.Deferral
I had to download the 3.0 + version for certain packages. dist.nuget.org/win-x86-commandline/v3.1.0-beta/nuget.exeAuroraauroral
This isn't working for me. Even after a successful nuget restore, msbuild isn't finding the referenced assemblies. Created a new question here #38100858Guido
Note that the "latest NuGet" executable above isn't necessarily the "latest" - it gave me v2.8. The nuget homepage has a link to latest nuget.exe which is 4.1.0 as at 2017-06-01Recitativo
@Recitativo Thanks, updated the answer with that info.Filamentary
I think this is the only nice solution when working with msbuild and nuget build targetMaidinwaiting
Best answer. I wanted to nuke the packages dir every time i am building my solution (through a bat file) and then restore it. So i downloaded the latest nuget.exe from nuget.org/downloads, put it in the root of my project and then i give the command "call "nuget.exe" restore solution.sln". Works like a charm, thanks a lotBase
this fails on the mac if you have UWP in the solutionDrambuie
C
56

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

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.

Crumpton answered 10/4, 2014 at 18:3 Comment(4)
You need to run "nuget update -self" before using the restore-command if your NuGet version isn't at least 2.7. My NuGet was version 2.1 and didn't recognize the "restore" command before updating.Buxom
"causes problems if you build those projects in another solution" I haven't run into any problems yet and we have 3 solutions with dozens of projects each (many shared across solutions). Maybe I got lucky?Kerchief
@NelsonRothermel the most notable problematic situation that can happen is projects referencing nuget-delivered dlls to an foreign solution's packages folder, which might not be available when you build a solution.Crumpton
@OwenJohnson We have one common package folder for all solutions, so that's probably why we haven't run into issues.Kerchief
T
40

UPDATED with latest official NuGet documentation as of v3.3.0

Package Restore Approaches

NuGet offers three approaches to using package restore.


Automatic Package Restore is 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.


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.

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


Command-Line Package Restore is 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.exe restore contoso.sln

The MSBuild-integrated package restore approach 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.

Translucent answered 10/3, 2014 at 14:17 Comment(6)
This is no longer recommended by nuget. See the docs. docs.nuget.org/docs/workflows/…Crumpton
@OwenJohnson, that doc isn't dated that I can see and I don't see how it says it is not recommended now? I'm on VS2013 and that button appears to work fine. I did not have the problem referenced, "So, you clicked "Enable Nuget Package Restore" and now your stuff doesn't build. The steps to fix it are painful, but less painful with this script. " github.com/owen2/AutomaticPackageRestoreMigrationScript Perhaps there is another doc that explains this further.Graver
Automatic package restore replaces the ms-build integrated restore. The document is the instructions on how to upgrade. If you aren't having problems with the msbuild-integrated method, you don't need to do anything. In the simplest cases, it works, but if you have CI servers, shared project references, or some other conditions, you might step on some nasty landmines and have incorrect hintpaths or other issues.Crumpton
Using this answer AND the doing the "remove old stuff" instructions"Performing the migration" at docs.nuget.org/consume/package-restore/… , I was able to find success.Devol
Looks like things have changed again with NuGet 4 and .net standard.Crumpton
dotnet run worked for me learn.microsoft.com/en-us/nuget/consume-packages/…Centigram
D
17

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 approach by the NuGet team.

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.
Drouin answered 10/3, 2014 at 17:13 Comment(8)
One of your steps is to remove <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />. Why would you do that?Khadijahkhai
if you use 'MSBuild-Integrated Package Restore' approach (by right-clicking your solution's Enable NuGet Package Restore menu item), the Visual Studio will add those lines into all project in your solution.Drouin
I think you're mistaken that is in the template itself. Without it your source files will not be built at all.Khadijahkhai
The change in project file just removes the package download task during the middle of build -- it doesn't break the build because the above solution downloads all dependent packages before the build starts.Drouin
I think he meant nuget.targets instead of Microsoft.CSharp.targets.Crumpton
docs.nuget.org/docs/workflows/… <- Here's the official docs of what Ying was trying to say.Crumpton
Ying is right... what everyone has ignored is the fact that Continuous Integration builds create their own temporary workspace AFTER the pre-build events, get sources, and then choke on NuGet references. This is THE FIX for TFS build automation.Comedown
For me, only adding the Nuget.Config, the .nuget folder (with nuget.exe and Nuget.Config) and adding .nuget as a project in the solution (doesn't appear in VS, I had to manually edit it in, copied it from another sln file) worked.Haunt
S
6

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

If you want to use this, you also have to use the new PackageReference, which means replacing the packages.config file with elements like this (do this in *.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).

Scanty answered 30/5, 2018 at 15:56 Comment(1)
You have to consider that the restore option of msbuild has subtle differences from nuget restore - see github.com/NuGet/Home/issues/7651#issuecomment-500842049 for example.Lomax
L
4

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

Lanti answered 6/7, 2015 at 13:1 Comment(0)
T
4

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

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

Timbering answered 13/4, 2016 at 8:48 Comment(3)
If you are constantly building from a fresh set of code (CI), this is the way to go.Hendrix
I kinda like this approach because it guarantees that each solution/project relies on the version of nuget it was created with. In due time this can prove vital if you work in a company with old projects which were created using old versions of nuget. A dev can maintain such projects without having to worry about whether the system-wide nuget.exe will break things because each project has its own "local flavor" of nuget.exe. As a last tip it's worth noting that with nuget 3.x+ we can restore packages like so: nuget.exe restore packages.config -PackagesDirectory path\to\packagesPregnancy
The problem I have with this approach is that you'll need to edit any subsequent project file to add the restore step. you can add a "InvokeProcess" activity in TFS2012 or a "NuGetRestore" activity in TFS2013 build template to have this step execute on the build server. for InvokeProcess, pass in the attribute "SourcesDirectory" in 2012. In TFS 2013, just fill in the values as required. there's lots of blogs on how to do this.Billman
S
2

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

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

Shortcoming answered 10/3, 2014 at 12:51 Comment(3)
There is no .nuget folder and never was. All packages.config files within project folders are in place.Glassy
i think NuGet.exe and NuGet.targets will automatically restore all missing packages while building the app and you lost your NuGet.exe and NuGet.targets files , thats y it cause errorsShortcoming
the .nuget folder is a Visual Studio generated folder, that appears only when you enable automatic package restore. It is useful to have the nuget.exe in your code repo, as you can reference it in your builds, as is the nuget.config (especially if you need to get packages from multiple repos).Aerophagia
R
2

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.

Ranique answered 3/9, 2015 at 17:30 Comment(1)
For VS 2015 and TFS, this will fix you up. The problem will be a reference not resolved, and often the issue is that the nuget package isn't being restored because the folder for the package already exists in the packages folder, but yet the package hasn't been fully expanded properly. (Such as missing a lib folder which should contain a .dll.) Delete the whole folder for the package within packages, and then right click at the solution level and choose to restore packages.Pittman
A
1

I had an issue with nuget packages not being included in a scripted nightly build that builds the sln file using devenv.exe.

I followed the advice from Microsoft, and the key step was updating the NuGet config in %AppData%/NuGet so that it contained:

<configuration>
    <packageRestore>
        <add key="automatic" value="True" />
    </packageRestore>
</configuration>
Aftertaste answered 8/6, 2018 at 8:54 Comment(1)
So I verified that when you change the settings in Visual Studio (most of the answers here)....the above is actually what gets changed. the other "key" is <add key="enabled" value="False" />.Devol
I
0

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

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

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)

Impenetrable answered 27/3, 2018 at 16:6 Comment(0)
P
-3

You can also use

Update-Package -reinstall

to restore the NuGet packages on the Package Management Console in Visual Studio.

Paronymous answered 2/5, 2019 at 11:6 Comment(1)
This is not an answer to this questionNolanolan

© 2022 - 2024 — McMap. All rights reserved.