Ole Albers
Ole Albers

Reputation: 9295

MsBuild does not find restored NuGet-Packages on Visual Studio Online

I try to build a solution stored in an external GIT-Repository on Visual Studio Online.

It has the following steps:

1: Git Restore - Works

2: NuGet Restore - Works

3: Build - Does NOT work

My first guess when looking at the logs is that MsBuild is not looking for the Packages where NuGet had stored them. Some Lines from NuGet Restore:

2018-03-14T21:10:11.0352862Z Completed installation of AngleSharp 0.9.9
2018-03-14T21:10:11.0353230Z Adding package 'AngleSharp.0.9.9' to folder 'D:\a\1\s\packages'
2018-03-14T21:10:11.0353563Z Added package 'AngleSharp.0.9.9' to folder 'D:\a\1\s\packages'
2018-03-14T21:10:11.0354972Z Added package 'AngleSharp.0.9.9' to folder 'D:\a\1\s\packages' from source 'https://api.nuget.org/v3/index.json' 'Microsoft.SharePointOnline.CSOM.16.1.7317.1200' to folder 'D:\a\1\s\packages' 

Some lines from MsBuild:

018-03-14T21:10:21.2105399Z PrepareForBuild:
2018-03-14T21:10:21.2105793Z   Creating directory "bin\Release\".
2018-03-14T21:10:21.2424947Z   Creating directory "obj\Release\".
2018-03-14T21:10:30.3569560Z ResolveAssemblyReferences:
2018-03-14T21:10:30.3570425Z   Primary reference "AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL".
2018-03-14T21:10:30.3670272Z ##[warning]C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(2041,5): Warning MSB3245: Could not resolve this reference. Could not locate the assembly "AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.

My solution/packages structure is:

....\mysolution\myproject\myproject.csproj
....\mysolution\myproject\packages.config

Current Config: NUGET enter image description here So how can I change the Nuget and/or msbuild-behavior to make this work?

(Update): To clear this up: I have this problem with every package. They all are in the packages.config, each one is downloaded from Nuget, but each one also isn't found from MsBuild

(Update2) The Commands generated are currently the following: NUGET:

D:\a\_tool\NuGet\4.4.1\x64\nuget.exe restore D:\a\1\s\AweCsomeO365\packages.config -PackagesDirectory D:\a\1\a\packages -Verbosity Detailed -NonInteractive -ConfigFile D:\a\1\Nuget\tempNuGet_22.config

MSBUILD:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" "D:\a\1\s\AweCsomeO365\AweCsomeO365.csproj" /nologo /nr:false /dl:CentralLogger,"D:\a\_tasks\VSBuild_(GUID)\1.126.0\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll";"RootDetailId=(GUID)|SolutionDir=D:\a\1\s\AweCsomeO365"*ForwardingLogger,"D:\a\_tasks\VSBuild_(GUID)\1.126.0\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll" /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=D:\a\1\a /p:ReferencePath=D:\a\1\a\packages /p:platform="anyCPU" /p:configuration="Release" /p:VisualStudioVersion="15.0" /p:_MSDeployUserAgent="VSTS_(GUID)_build_4_22

I replaced the GUIDs; tempNuGetConfig is something that seems to be generated by VSTS dynamically

Still. even if the log states that nuget stores the packages

Added package 'AngleSharp.0.9.9' to folder 'D:\a\1\a\packages'

MsBuild does not seem to find them there:

 For SearchPath "D:\a\1\a\packages".
2018-03-16T13:57:42.4625155Z           Considered "D:\a\1\a\packages\AngleSharp.winmd", but it didn't exist.
2018-03-16T13:57:42.4625456Z           Considered "D:\a\1\a\packages\AngleSharp.dll", but it didn't exist.
2018-03-16T13:57:42.4625730Z           Considered "D:\a\1\a\packages\AngleSharp.exe", but it didn't exist.

VSTS-Configurationvalues:

MsBuild: /p:ReferencePath=$(Build.StagingDirectory)\packages

Nuget-DestiantionDirectory: $(Build.StagingDirectory)\packages

(update3): I have no solution file, but only a csproj-file in that repository

Upvotes: 5

Views: 10185

Answers (4)

tobriand
tobriand

Reputation: 1167

The answers here are largely right. However it's worth noting another cause that can result in this behaviour. My toolchain was using Azure DevOps which is basically the same as Visual Studio Online, just a few years later.

Cause:

  • Reference your project from a different solution (cross-repo), for instance for debugging purposes
  • Update NuGet references in the problematic project from the external place you referenced it from

What this does is make use of the solution location for packages when the package gets installed.

For .Net core/standard projects, using Update-Package -reinstall appears to fix things. However, for .Net Framework projects, even though packages.json may get rebuilt, the <HintPath /> node in the .csproj gets left as is - with a reference to a packages folder that Azure will never create.

Simple fix:

  1. Right click on the offending solutions locally, and choose Unload
  2. Right click on the unloaded project, choose edit .csproj
  3. Find any hintpaths that look like ../../OtherRepo/packages (the slash in use may vary), and change them to ../packages
  4. Confirm the solution does build locally still
  5. Push the changes to Azure, and cross your fingers

This approach will fix the issue caused by consolidating / updating packages from the wrong place rather than requiring a change to the build pipeline to spoof that location (which in may case, wasn't working very well either).

Upvotes: 1

Ole Albers
Ole Albers

Reputation: 9295

The issue was that inside the project there was a hintpath for the packages directing to a location that was not within the GIT-Repository (and shouldn't):

  <Reference Include="AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
      <HintPath>..\..\AweCsome365Test\packages\AngleSharp.0.9.9\lib\net45\AngleSharp.dll</HintPath>
    </Reference>

My original approach was to define a target directory to NuGet and a Source Directory for MSBuild to use another location to the packages that both understand.

The issue though (as far as I understand) is, that NuGet always creates a subfolder-structure "./packages/{PackagesName}/lib/net45/{file}" and MSBuild does not look recursivly when setting "./packages" as source path.

The above is just an explanation for the future guy running into the same problem

So my solution was to mimic the local behavior for nuget and changing the output directory to match the HintPath (even if there is no "AweCsome365Test")-directory in the repository: Nuget Destination directory setting

(I will leave this question open as this solution smells fishy. If anyone has a better solution that allows to chain nuget and msbuild without using the HintPath I am happily willing to spend my bounty on it)

Upvotes: 6

jcwmoore
jcwmoore

Reputation: 1173

I believe that your MSBuild "ReferencePath" parameter is not correct. you are telling MS Build that all your references (nuget packages and their dlls included) are going to be located at "D:\a\1\a\packages" but that is not where nuget will download and store the packages and dlls. Nuget will download and extract files into D:\a\1\a\packages\{packageName}\{version}\lib\{environment}\package.dll. I think you need to remove that last parameter (ReferencePath) from your MSBuild arguments.

I also noticed that your PackageLocation parameter is not the same as the destination for the NuGet restore task, do you need to add the "\packages" to that parameter like the destination in the restore task?

Upvotes: 1

Shawn Miller
Shawn Miller

Reputation: 79

Change the nuget restore destination directory to $(Build.SourcesDirectory)\packages and remove the msbuild ReferencePath parameter.

Upvotes: 0

Related Questions