visual-studio-2017nuget

Missing file NuGet.targets on existing project


The scenario is:
1. Created a NEW solution
2. ENABLED download missing packages
3. Add projects to solution that already exists and depends on nuget packages
4. Building the solution generates an error:

... The missing file is <solution folder>\.nuget\NuGet.targets.

Why? Have missing something?

I'm using Visual Studio 2017 Pro on Windows 10

All my searches answer about the scenario where create a new solution and adds a new project that depends on nuget package, that's ok, but when have an existing project, nothing.


Solution

  • <solution folder>\.nuget\NuGet.targets is a file that NuGet's Visual Studio extension used to add in Visual Studio 2010, 2012 and 2013 when you right click on the solution and select "Enable NuGet Package Restore". It would then add an import in all of your project files to import the targets file. I was recently investigating a customer issue and as part of that investigation I found it made the following changes. Near the top of the csproj, it adds something like this:

    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
    <RestorePackages>true</RestorePackages>
    

    and near the end of the csproj it adds somthing like this:

    <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
    <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
      <PropertyGroup>
        <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
      </PropertyGroup>
      <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
    </Target>
    

    So, the problem is that you're creating a new solution, but using existing project files that have been modified in this way. One option is to edit your csrpoj files and remove these changes. Another option is to create new projects, in addition to the new solution, and then copy all your code and content files.

    The only disadvantage is if you build on a CI server and use packages.config, your build script needs to explicitly restore NuGet packages. Since VS 2019 version 16.5, it has been possible to use msbuild -t:restore your.sln -p:RestorePackagesConfig=true. If you're using an older version of Visual Studio, you'll need to download NuGet.exe and run nuget.exe restore yourself. Whereas projects that use this NuGet.targets could just build the solution and msbuild would execute nuget restore as needed. One advantage of no longer using NuGet.targets is that restoring the whole solution is faster than restoring project by project. Visual Studio automatically restores packages on build, even in VS2010, VS2012 and VS2013, so personally I discourage the use of using this feature, even if you use those old versions of Visual Studio. The benefit of reducing your build script by one step is not worth the issues it brings, in my opinion.