Home: Reference assembly HintPath may become incorrect when same project is added to different .sln files

Created on 8 Jun 2015  路  19Comments  路  Source: NuGet/Home

Hi.
There is an issue with the approach how MSbuild discovers and handles referenced assemblies from Nuget and HintPath tag. See issue 107 in MSBuild.
Msbuild team has other priorities and advised that maybe this may be addressed with Nuget enhancements.

In general - the issue is how HintPath tag is used - it uses relative-to-solution-fle dir to reference assemblies from nuget packages - thus this approach breaks if same project is included into multiple solutions in different folders.

One of potential fixes is to introduce and use msbuild property like $(NugetPackagePath) so it'll be re-evaluated on each build. E.g.

<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>$(NugetPackagesPath)\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>

I'm not 100% sure it must be fixed with Nuget, it looks like MSBuild issue, not Nuget one, but adding that Property can help with some other scenarios too.

Most helpful comment

@yishaigalatzer is there any good reasons to not do what RelativeHintPaths do by default, i.e. use hint paths relative to $(SolutionDir) regardless of where project is located within solution hirararchy:

<Reference Include="EntityFramework">
    <HintPath>
        $(SolutionDir)\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
    </HintPath>
</Reference>

It will solve project included in multiple solutions issue, assuming package restore enabled in all of them. And issues related to project movement down or up in folders hierarchy within single solution.

All 19 comments

This is a great issue (I hit it myself numerous times). Unfortunately NuGet cannot fix it in its current form, and this is the same behavior as add references.

You will have to implement something like your suggestion yourself (and better yet, completely avoid hintpath!) instead use something like:

<Reference Include="..\packages\LibGit2Sharp.0.1\$(Configuration)\LibGit2Sharp.dll">
    <Name>LibGit2Sharp.dll</Name>
</Reference>

In NuGet 3 at some point we are going to support transitive restore which is going to restore all packages to a common folder and not change your project file at all. We are already building NuGet this way see: https://github.com/NuGet/NuGet3

@yishaigalatzer is there any good reasons to not do what RelativeHintPaths do by default, i.e. use hint paths relative to $(SolutionDir) regardless of where project is located within solution hirararchy:

<Reference Include="EntityFramework">
    <HintPath>
        $(SolutionDir)\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
    </HintPath>
</Reference>

It will solve project included in multiple solutions issue, assuming package restore enabled in all of them. And issues related to project movement down or up in folders hierarchy within single solution.

The point is that nuget does not touch the project files directly for adding references, it uses dte that makes it work across different project systems and flavors.

Unfortunately NuGet cannot fix it in its current form, and this is the same behavior as add references.

@yishaigalatzer yeah, but I believe that issue can be fixed using `$(SolutionDir) in current form

I might have not been clear enough. The way nuget adds reference to a project is by calling visual studio to add the reference, it does not attempt to understand the csproj file format or understand how references are being added. Which is what makes it work across various project systems iterations, with DTE being the common contract across different project systems.

Also note that $(solutiondir) is not a global solution as the packages folder is configurable.

IMHO hintpaths are something that shouldn't be used at all, they lead to conflicts with GAC when things cannot be found, and straight links are preferable, but the same problem statement exists.

Because of this we are moving NuGet to a different model where we never modify the project at all and packages are stored in one global location which resolves this issue in a different and hopefully better.

+1

Bump. anyone know the progress of a fix for this? It is causing problems at my own work.

I've been running into this as well and any kind of searching on hint paths leaves to a ton of issues with it.

Nuget 3 recently added support for a project.json but as far as I can tell it's only for Windows 10 UWP, ASP.NET 5+ and a few other types of projects. So thats great for all the new stuff - but the new framework is a bit of a hot mess right now - I wish we could use this for existing projects with nuget 3 and/or have an override flag get passed into to specify the packages/paths....

@centur @jmdjr @Ashtonian @yishaigalatzer

NuGetReferenceHintPathRewrite

Works great for me.

After reading all this, I'm scratching my head wondering how setting the "common location" to a particular user's roaming profile makes this better, since ......\Users\Eric\AppData wouldnt work if the project path is even one level different?

At least ..\packages makes exactly one assumption: that packages repo is stored X levels higher than the project

-    <Reference Include="Google.Maps, Version=0.10.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\gmaps-api-net.0.10.1\lib\net\Google.Maps.dll</HintPath>
+    <Reference Include="Google.Maps, Version=0.14.51.34051, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\..\Users\Eric\AppData\Roaming\NuGet\gmaps-api-net.0.14.51\lib\net\Google.Maps.dll</HintPath>

Clearly the DTE contracts weren't designed with package management in mind, and should perhaps either be augmented to include that concept which IMO is very important in development environments anyways...

The only solution that i've found that works when folks have their package caches in different places is to run update-package -reinstall for the project or vs solution.

Man this is still an issue. Nobody has bothered to address it?

This frequently causes problems with developers not having same name as myself. Frequently. Problem.

Why didnt nuget use C:\ProgramData\nuget\packages ??? at least that would be 90% correct, unless of course somebody installs windows on a D drive. Ugh.

should be $(NugetPackagesDir) or similar.

update-package -reinstall still writes bogus hintpaths that will fail with a build server because somewhere its using HintPath=%USERPROFILE%\AppData\Roaming\nuget, again wont work because %USERPROFILE% on the build server will be a completely different path

Always lovely to have to figure out nuget packaging apparatus when its supposed to do this stuff itself!
https://ci.appveyor.com/project/EricNewton/datetimecomparer/build/1.0.11

The PackageReference panacea doesn't address this?

PackageReference didn鈥檛 work for me after clean slate convert very simple project from vs2015 to vs2017. Used vs2017 net framework class library template which still uses hintpath. Tried to start over again clean slate and use the Microsoft.Net.Sdk project type which uses packagereference but still had problems getting builds to work on appveyor with that

@ericnewton76 you can select the type of reference to use for "classic" projects in the NuGet options as described in NuGet's blog post (section "What about other project types that are not .NET Core?"):

options

A completely different option would be to add a NuGet.config high enough in the directory hierarchy that specifies the packages directory relative to itself so all solutions below this path use the same directory and restore paths are the same. I use that for a legacy setup that uses svn submodules so that the submodule solutions and main solution get correct hint paths. This also works in older VS/NuGet versions.

This issue has just hit us as well. We have hundreds of projects in about 6 different solutions. The largest being about 300 projects in the main solution. All are in different folders, and some refer to specific framework projects that we have.

NuGet in the current state is a nightmare. The very first post here describes the perfect solution using $(NugetPackagePath). I can't believe that this simple fix has not been applied yet.

I'm facing this problem as well and finding no working solution. I can't believe this simple issue has been around for over 3 years and hasn't been fixed.

  1. Still a problem.

I have the same issue, the Hint Path point to my userprofile folder C:\User\\ which does not exist in my colleagues's PC which make their build failed.
Then I realize that I didn't add Nuget package but using Reshapper to solve the reference which cause above error.
Once I add nuget package, the reference points to C:\Program Filesdotnet\sdk\NuGetFallbackFolder\ (I'm using .net core) correctly.
Hope it help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blackcity picture blackcity  路  3Comments

philippe-lavoie picture philippe-lavoie  路  3Comments

clairernovotny picture clairernovotny  路  3Comments

LordMike picture LordMike  路  3Comments

skofman1 picture skofman1  路  3Comments