Remove solution directory path from hintpath and solutiondir tags


If I import an existent project to my solution and install a Nuget package with package restore, the project contains a solutiondir tag similar to:
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\path\to\remote\solution\</SolutionDir>
and an hintpath like:

in my opinion this is very bad. Why Nuget can't put "..\" as $(solutiondir) parameter and "$(solutiondir)\packages\" as hintpath? with these modifications and package restore we are able to create the package folder where needed. or not?


drewmiller wrote May 7, 2012 at 8:57 PM

@ManuelSpezzani, The SolutionDir variable is only available in Visual Studio. Many people also build the solution outside of VS via MSBuild, so we can't safely use it a hint path. We add SolutionDir to projects when we enabled Package Restore, but not all projects (in fact, very few yet) use package restore, so we can't depend on that.

We could consider adding SolutionDir when you install a package as we do in package restore. We'd have to consider the consequences.

(For history of this discussion, see http://nuget.codeplex.com/workitem/1923.)

drewmiller wrote May 7, 2012 at 9:00 PM

Sorry, I should have been more clear, that the code that adds the hint path isn't related to package restore, hence the seeming disconnect. In addition to considering generally adding SolutionDir, I guess we could at least make adding a NuGet reference smart enough to see if it is available, or at least if package restore is enabled.

jagui wrote Aug 9, 2012 at 10:03 AM

In my case I have two solutions, one contains some common libraries, the other one contains more projects as well as the common libraries. If the hint path was set to $(SolutionDir)\packages\package the build will work regardless of the solution I'm building. The difference is that in one case the packages are downloaded to the common libraries's solution packages folder and on the other are copied to the application's solution

DanHarman wrote Mar 27, 2013 at 1:07 AM

This is actually a bit of a horror when using tfs online build preview. I had moved a few projects into sub directories and not realised how dependent the package restore feature was on the hintpath. I hadn't updated the hint path when nesting and was getting unable to resolve package reference problems, but only on the build server, it was all fine on my machine.

It would be nice if we could make the project files less fragile when using package restore. Its never good when you have to start hacking at csproj just to relocate a project.

dotnetjunky wrote Jun 25, 2013 at 6:18 PM

dotnetjunky wrote Sep 13, 2013 at 11:27 PM

The MS-Build based package restore model has been replaced with the new restore implementation model in 2.7. We recommend everyone to move to the new model. As a result, we will not fix this bug.

** Closed by dotnetjunky 09/13/2013 4:27PM

philwray wrote Oct 3, 2013 at 10:54 AM

This has been closed - but I don't see how the new package restore model fixes this.
When I reference the same project from two different solutions in two different directories the package restore still fails as the hintpath in the csproj still contains a relative path to the project.

Can you clarify whether there is now a workaround in the new restore model please?

deepakverma wrote Oct 3, 2013 at 6:57 PM

re-opening as per comment from @philwray

RanjiniM wrote Oct 28, 2013 at 8:26 PM

When verifying the fix for this bug, please verify https://nuget.codeplex.com/workitem/2999 also. Closing https://nuget.codeplex.com/workitem/2999 as a dupe of this one.

feiling wrote Dec 6, 2013 at 5:55 PM

We'll revisit this in 2.9.

JeffHandley wrote Dec 18, 2013 at 1:28 AM

Instead of using $(SolutionDir), we'll want to use $(NuGetRepositoryPath).

Here's my proposal:
  1. When NuGet is adding a reference, it will check to see if the $(NuGetRepositoryPath) property property exists.
  2. If the property does exist, the hint path will be rooted on $(NuGetRepositoryPath) instead of a static value
  3. If the property does not exist, the hint path will still work like it does today
This would allow advanced users to create the $(NuGetRepositoryPath) property in their projects to make it dynamic, while mitigating the risk of the feature. Additionally, nuget.exe config repositoryPath -aspath can be used from the command-line to get the effective repository path for a project. This output can be used as a command-line argument when building the project file through msbuild, which would then respect the dynamic hint paths, even allowing them to be changed at build time when the project is built under multiple solutions.

Andy99Andy99 wrote May 16 at 2:38 PM

There appears to be duplicate issues 3897 and 4061.

AVee00 wrote Jun 13 at 3:32 PM

I like JeffHandley proposal, but I'd change 3 to:
If the property does not exist, create it and set it to the path currently used.

This should behave the same, but has the benefit of always having a $(NuGetRepositoryPath) in the project. That would allow builds outside Visual Studio to just assume the property exists, which ensures all tooling (build servers mainly) will just work against a project which was created in Visual Studio without any manual editing of the project file. It would also allow a build server to use a single $(NuGetRepositoryPath) for lots of projects out of the box.

philn5d wrote Jul 2 at 6:44 PM

Building off JeffHandley's suggestion -

I put this in a project file and it works for me with solution build and msbuild from command line:

<When  Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">

<When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
        <NuGetRepositoryPath >$(SolutionDir)</NuGetRepositoryPath>
<Reference Include="AutoMapper.Net4">

JeffHandley wrote Jul 2 at 9:36 PM

$(NuGetRepositoryPath) should include the "packages" part too. If you set the RepositoryPath config setting, it overrides the "packages" folder name.