Debugging NuGet Package Restore

3 minute read

Package Restore Internals

When enabling NuGet package restore, the NuGet Visual Studio extension modifies your projects in the following way:

  • A .nuget folder is created next to your solution, containing MSBuild targets and the nuget.exe command line tool.
  • Your existing projects that already consume NuGet packages are modified: the MSBuild element is added and set to True, and an statement is configured to import the NuGet MSbuild targets. (and technically, a property is set as well, allowing you to configure the location of your solution if you deviate from the default convention of having a projectdir for each project in your solution: $(SolutionDir)\ProjectDirA\ProjectA.csproj)</li> </ul>

    Check the NuGet documentation to learn how to set up NuGet package restore. I'll focus on the issues now.

    Debugging Checklist

    Depending on the symptoms of your issue, you can start investigating locally, or working your way back starting from the build server. Obviously, the easiest way is to check if all runs fine locally.

    • Clear your $(SolutionDir)\Packages folder (except for the repositories.config file)
    • Clean your solution (delete bin & obj folders)
    • Clear your local machine NuGet cache (%LocalAppData%\NuGet\Cache)

    Rebuild your solution and check if everything compiles OK and the correct packages are installed.

    In Visual Studio

    • By default, NuGet Package Restore enables restore only for those projects that already consume NuGet packages. If you first enabled package restore and then started consuming packages, it is possible that some projects aren't configured properly. You can verify this by checking whether the project files contain the true MSBuild property.
    • NuGet Package Restore assumes you have a solution in a root directory $(SolutionDir) and all projects have their own subdirectory (e.g. $(SolutionDir)\ProjectDirA\ProjectA.csproj). If you deviate from this convention, you have to manipulate the MSBuild element in the project files accordingly (using relative paths!).</li>
    • Ensure the nuget.targets file element is pointing to the correct URL. You can define multiple package sources using a semicolon separator. The order in which they are defined is also the order in which NuGet will look for your packages. When using paths that contain spaces, also ensure to put double quotes around the entire property value declaration (e.g. "\some unc\path;https://some url/feed/packages")</li>
    • If you upgraded some regular references to NuGet package dependencies, ensure the in the project file for that reference is pointing towards the correct location in the packages folder.</li> </ul>

      In Version Control

      • No matter what type of VCS you are using, NuGet Package Restore requires the .nuget folder to be checked-in, including the nuget.targets, nuget.config and nuget.exe.
      • Double-check whether you are having the actual nuget.exe command line in the .nuget folder, and not the bootstrapper. The commandline is around 600Kb in file size, the bootstrapper 15Kb. The bootstrapper requires internet access, and has been made obsolete now. It might be revived in the future, but for now, you should make sure you use the nuget.exe command line tool instead. You can get the nuget.exe command line manually as well by downloading it here. Unzip it and replace your 18Kb nuget.exe by the one you'll find inside the package.
      • Ensure you checked in the Packages\repositories.config file. When using TFS, you'll be better off when defining appropriate workspace mappings for this.

      On The Build Server

      • NuGet Package Restore requires a consent (due to privacy policy & legal requirements). This can be set using a system-wide environment variable, which is explained on the NuGet Blog.
      • When using a secured feed which requires you to authenticate before consuming anything, you'll have to configure the required credentials in the NuGet.config. Ensure you are running this under the build service account. If the service account cannot remote desktop into the server but you can, then you might run a command prompt under another user by running the following from the command line:

        runas /user:DomainName\TfsBuildServiceAccountName cmd
        
        You'll be prompted for the password and a new command prompt should open. In this new command prompt, follow the below instructions to save authentication information for a given package source.

        nuget.exe sources add -name [feedName] -source [feedUrl]
        nuget.exe setapikey [apikey] -source [feedUrl]
        nuget.exe sources update -Name [feedName -User [username] -pass [password]
        
        When using MyGet, we recommend you to use/create a specific user account for the build service account, if only to avoid you breaking all builds when changing your own password or apikey :)

      Hope this helps anyone!

Leave a Comment