298

I have the following convention for most of my projects:

/src
    /Solution.sln
    /SolutionFolder
        /Project1
        /Project2
        /etc..
/lib
    /Moq
        moq.dll
        license.txt
    /Yui-Compressor
        yui.compressor.dll
/tools
    /ILMerge
        ilmerge.exe

You'll notice that I do not keep external libraries inside the source folder. I'm also very interested in using NuGet but don't want these external libraries inside the source folder. Does NuGet have a setting to change the directory that all packages are loaded into?

Lorenzo
  • 28,103
  • 43
  • 117
  • 208
TheCloudlessSky
  • 17,698
  • 13
  • 68
  • 113
  • 10
    Yes, yes, yes! This is exactly the project structure I use (or very very nearly), and I've always wondered with NuGet could support it... – Noldorin Feb 28 '12 at 23:29
  • I've gone into detail on how to do this with this following answer: http://stackoverflow.com/a/19466173/564726. You often need to remove the solutionDir option from the restore command for it to work correctly. – BrutalDev Oct 19 '13 at 12:56
  • 2
    I put the .sln at the same level as your top level folders. :) – Ian Warburton Oct 19 '14 at 15:25

16 Answers16

247

It's now possible to control which folder the packages are installed into.

http://nuget.codeplex.com/workitem/215

Edit: See Phil Haack's comment on Dec 10 2010 at 11:45 PM (in the work item/the link above). The support is partially implemented in 1.0, but is not documented.

According to @dfowler: Add a nuget.config file next to the solution with this:

<settings>
<repositoryPath>{some path here}</repositoryPath>
</settings>

There is a nuget package for creating the package folder override.

Update for version 2.1

As Azat commented, there is now official documentation on how to control the package locations. The release notes for 2.1 specifies the following configuration in a nuget.config file (see the release notes for a description of valid places to put the config files and how the hierarchical configuration model works):

<configuration>
  <config>
    <add key="repositoryPath" value="C:\thePathToMyPackagesFolder" />
  </config>
  ... 
</configuration>

This would change the packages folder for the configuration level you put the file in (solution if you put it in the solution directory, project in project directory and so on). Note that the release notes state:

[...] if you have an existing packages folder underneath your solution root, you will need to delete it before NuGet will place packages in the new location.

PHeiberg
  • 28,455
  • 6
  • 51
  • 79
  • As mentioned below, it is *not* yet possible, but, such a feature has been proposed. Up vote the issue to help get it in: http://nuget.codeplex.com/workitem/215 – stephen Jan 19 '11 at 15:00
  • Haacked wrote Dec 10 2010 at 11:45 PM @dmarsh. WE've actually partially implemented this feature in 1.0, but we left it undocumented and unsupported because we found some tricky design issues we need to work through. I don't recall exactly what they are. If you look at the source though, you may be able to figure out how to enable thi – PHeiberg Jan 19 '11 at 20:33
  • 5
    It actually is possible using the above config file. The reason it was de-emphasized is because we haven't though through the workflow of enabling this through the UI and other means so expect some quirkiness. – davidfowl Jan 21 '11 at 03:57
  • I am just about to try this but the first thing I notice is the potential conflict if you have multiple solutions because of the repositories.config file in the packages directory. How would that work if the packages are used by multiple solutions, which is what I want. It is redundant to have multiple packages directories all with the same files in them. – Rob Kent Jun 08 '11 at 12:04
  • Okay, I have now tried this and it seems to work although the repositories.config file now shows the path to whichever project download the package: Is that a problem, I wonder? – Rob Kent Jun 08 '11 at 12:32
  • 5
    See http://reviewboard.nupack.com/r/131/ for a full description by @dfowler of how nuget.config works. For example, a valid nuget.config would look like this: lib – Lee Harold Jul 09 '11 at 02:53
  • @LeeHarold the url is dead... And I'm not able to get nuget to install packages at a different folder. – peirix Oct 18 '11 at 13:11
  • @ferventcoder is there documentation? I can't seem to make that work. – Mike Cole Oct 27 '11 at 04:09
  • @MikeC. It's possible that this has finally been disabled in a recent version. There is no documentation, that's the point of undocumented features. ;) – ferventcoder Oct 31 '11 at 07:39
  • 6
    http://docs.nuget.org/docs/release-notes/nuget-2.1 See "Specify ‘packages’ Folder Location" paragraph – Azat Oct 17 '12 at 09:33
  • Is it just me, or does this only work for the package manager console? When I create a config file in the same dir as my solution it works when I install the packages by console. But when I'm installing them by the visual manager it won't install the packages at all.. – Maarten Kieft Mar 14 '13 at 10:24
  • 1
    I can confirm the new way of doing things in 2.1+ does not work. And there are bugs about it on codeplex: http://nuget.codeplex.com/workitem/2921. – Case Mar 22 '13 at 02:14
  • 5
    The second version works for me, I use latest NuGet, and now two solutions can share the same repo. I think it may not work some people because they might use absolute paths? It seems that absolute vs. relative path matters. – Csaba Toth Apr 30 '13 at 15:33
  • This NuGet config reference page made how the config chaining works crystal clear: http://docs.nuget.org/docs/reference/nuget-config-file. Also, it seemed like I needed to close my solution and reopen it after adding the override configs in the solution directory before it restored them to the right place. – gabe Feb 12 '14 at 22:29
  • I've placed nuget.config into my team directory root and it worked fine, but I had to restart Visual Studio in order to achieve it. Version 2.6.40627.9000 – Gobe Jan 13 '15 at 15:45
  • This doesn't work for my current situation - where I want the *project* to determine where its packages are, not the solution. – Shawn South Jan 13 '15 at 19:06
  • Be aware that changing the packages location will break all existing references to NuGet packages, as the HintPath still points to the old location. – Tom Lint Nov 04 '16 at 09:52
  • After creating this file I had to uninstall and install again all the Nuget packages already installed so that the projects could find them. – AxelWass Jun 21 '17 at 16:25
  • 2
    Remember if doing this from Visual Studio, **restart Visual Studio** after adding/modifying the `nuget.config` file. I found this out [the hard way](https://stackoverflow.com/questions/50685518/visual-studio-2017-nuget-config-at-solution-folder-not-recognized#comment89151735_50715723). – user692942 Jun 28 '18 at 11:28
65
  1. Created a file called "nuget.config".
  2. Added that file to my solutions folder

this did NOT work for me:

<configuration>
  <config>
    <add key="repositoryPath" value="..\ExtLibs\Packages" />
  </config>
  ... 
</configuration>

this did WORK for me:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>
ShaneKm
  • 18,605
  • 41
  • 141
  • 250
  • Only the second solution works: http://docs.nuget.org/docs/reference/nuget-config-file – cheesemacfly Nov 06 '13 at 21:44
  • 16
    It depends on the version of NuGet that you are using. – Bronumski Nov 27 '13 at 13:45
  • 2
    Note that relative paths are relative to the solution so if your projects are at different levels then it won't work. – Nine Tails Jul 21 '15 at 15:49
  • 2
    This works fine for VIsual Studio 2013, but if I am using Visual Studio 2015 then it still install packages in packages folder near the sln file, – fhnaseer Aug 31 '15 at 12:24
  • @FaisalHafeez did you find a solution for VS 2015? I tried using with but it doesnt work for me. it wont override the default location. – Emil Aug 20 '16 at 16:27
  • @batmaci - Bronumski is right, on my VS 2015 the first version on this answer (the one that "did NOT work" for ShaneKm actually worked for me. – BornToCode May 08 '17 at 19:28
43

Okay for the sake of anyone else reading this post - here is what I understand of the myriad of answers above:

  1. The nuget.config file in the .nuget folder is relative to that folder. This is important because if your new folder is something like '../Packages' that will put it where it always goes out of the box. As @bruce14 states you must do '../../Packages' instead

  2. I could not get the latest nuget (2.8.5) to find a packages folder outside of the standard location without enabling package restore. So once you enable package restore then the following should be added to the nuget.config file inside of the .nuget folder to change the location:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
    
  3. (This is important) If you make ANY changes to the package folder location inside of the nuget.config files you must restart visual studio or close/reload the solution for the changes to take effect

Robert Petz
  • 2,574
  • 4
  • 21
  • 51
  • 7
    Trust me, your #3 point saved my day. I was crazy from last 3 hours until I read your #3 point. :'( Thank u so much bro! – hellodear Jul 18 '17 at 11:15
26

A solution for Nuget 3.2 on Visual Studio 2015 is:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
        <add key="repositoryPath" value="../lib" />
    </config>
</configuration>

Using forward slash for parent folder. Save above file (nuget.config) in solution folder.

Reference is available here

SharpCoder
  • 15,708
  • 34
  • 126
  • 225
phuongnd
  • 980
  • 11
  • 29
16

The solution proposed in release notes for 2.1 doesn't work out-of-the-box. They forgot to mention that there is code:

internal string ResolveInstallPath()
{
    if (!string.IsNullOrEmpty(this.OutputDirectory))
    {
        return this.OutputDirectory;
    }
    ISettings settings = this._configSettings;

    ...
}

which prevents it from working. To fix this you need to modify your NuGet.targets file and remove 'OutputDirectory' parameter:

    <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(RequireConsentSwitch)</RestoreCommand>

So now, if you add 'repositoryPath' config somewhere in NuGet.config (see the release notes for a description of valid places to put the config files), it will restore all packages into single location, but... Your .csproj still contains hints to assemblies written as relative paths...

I still don't understand why they went hard way instead of changing PackageManager so it would add hint paths relative to PackagesDir. That's the way I do manually to have different package locations locally (on my desktop) and on build agent.

<Reference Include="Autofac.Configuration, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
  <Private>True</Private>
  <HintPath>$(PackagesDir)\Autofac.2.6.3.862\lib\NET40\Autofac.Configuration.dll</HintPath>
</Reference>
Dmitry Naumov
  • 697
  • 6
  • 12
  • 1
    You are absolutely right. At my company we actually use a version of NuGet that we modified ourselves that does exactly what you are describing, i.e. it adds HintPaths relative to the Packages Dir not relative to the location of the project file. This works perfectly well. Unfortunately we never got around to trying to bring in the changes we made to NuGet to the official version, but maybe it's time to do that now... – afrischke Mar 14 '13 at 22:04
  • 1
    @afrischke: that would be great if you could do that. thanks. Any idea when this might happen? – sgtz Mar 27 '13 at 13:43
12

In addition to Shane Kms answer, if you've activated Nuget Package Restore, you edit the NuGet.config located in the .nuget-folder as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <repositoryPath>..\..\ExtLibs\Packages</repositoryPath>
</configuration>

Notice the extra "..\", as it backtracks from the .nuget-folder and not the solution folder.

user
  • 699
  • 8
  • 17
11

None of this answers was working for me (Nuget 2.8.6) because of missing some tips, will try to add them here as it might be useful for others.

After reading the following sources:
https://docs.nuget.org/consume/NuGet-Config-Settings
https://github.com/NuGet/Home/issues/1346
It appears that

  1. To make working Install-Package properly with different repositoryPath you need to use forward slashes, it's because they are using Uri object to parse location.
  2. Without $ on the begining it was still ignoring my settings.
  3. NuGet caches config file, so after modifications you need to reload solution/VS.
  4. I had also strange issue while using command of NuGet.exe to set this option, as it modified my global NuGet.exe under AppData\Roaming\NuGet and started to restore packages there (Since that file has higher priority, just guessing).

E.g.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
  <config>
    <add key="repositorypath" value="$/../../../Common/packages" />
  </config>
</configuration>

You can also use NuGet command to ensure that syntax will be correct like this:

NuGet.exe config -Set repositoryPath=$/../../../Common/packages -ConfigFile NuGet.Config
Roman Badiornyi
  • 1,461
  • 13
  • 28
10

In order to change the path for projects using PackageReference instead of packages.config you need to use globalPackagesFolder

From https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file

globalPackagesFolder (projects using PackageReference only)

The location of the default global packages folder. The default is %userprofile%.nuget\packages (Windows) or ~/.nuget/packages (Mac/Linux). A relative path can be used in project-specific nuget.config files. This setting is overridden by the NUGET_PACKAGES environment variable, which takes precedence.

repositoryPath (packages.config only)

The location in which to install NuGet packages instead of the default $(Solutiondir)/packages folder. A relative path can be used in project-specific nuget.config files. This setting is overridden by the NUGET_PACKAGES environment variable, which takes precedence.

<config>
    <add key="globalPackagesFolder" value="c:\packageReferences" />
    <add key="repositoryPath" value="c:\packagesConfig" />
</config>

I put Nuget.config next to my solution file and it worked.

Manny
  • 308
  • 3
  • 11
9

For .NET Core projects and Visual Studio 2017 I was able to restore all packages to relative path by providing this configuration:

<configuration>
  <config>
    <add key="globalPackagesFolder" value="lib" />
  </config>
  ... 
</configuration>

Based on my experience the lib folder was created on the same level where Nuget.config was found, no matter where sln file was. I tested and the behavior is same for command line dotnet restore, and Visual Studio 2017 rebuild

  • I tried this. I set the `globalPackagesFolder` key to my project's package folder. I tried to add a single package with `dotnet add package MyPackage`. `nuget.exe` downloaded the entire framework of 83 .NET packages into that folder. That's not what I intended. I just wanted my single MyPackage in my local, source-controlled package folder. – Wallace Kelly Jul 20 '17 at 15:01
  • DO NOT DO THAT! This will overwhelm your HDD pretty fast as the entire framework packages will be download every time you create a new app. – Alaa Masoud Feb 19 '19 at 08:25
  • 1
    as per this answer to another question: https://stackoverflow.com/a/47407399/4572240 "respositoryPath is used for packages.config projects, globalPackagesFolder is used for PackageReference projects". – Siderite Zackwehdex Jul 09 '19 at 13:47
8

The config file in the accepted answer works for me in VS2012. However, for me it only works when I do the following:

  1. Create a new project in VS.
  2. Exit VS - this seems to be important.
  3. Copy the config files to the project folder.
  4. Restart VS and add packages.

If I follow those steps I can use a shared package folder.

Harald
  • 929
  • 1
  • 12
  • 27
7

One more little tidbit that I just discovered. (This may be so basic that some haven't mentioned it, but it was important for my solution.) The "packages" folder ends up in the same folder as your .sln file.

We moved our .sln file and then fixed all of the paths inside to find the various projects and voila! Our packages folder ended up where we wanted it.

NickNuke
  • 183
  • 1
  • 9
5

UPDATE for VS 2017:

Looks people in Nuget team finally started to use Nuget themselves which helped them to find and fix several important things. So now (if I'm not mistaken, as still didn't migrated to VS 2017) the below is not necessary any more. You should be able to set the "repositoryPath" to a local folder and it will work. Even you can leave it at all as by default restore location moved out of solution folders to machine level. Again - I still didn't test it by myself

VS 2015 and earlier

Just a tip to other answers (specifically this):

Location of the NuGet Package folder can be changed via configuration, but VisualStudio still reference assemblies in this folder relatively:

<HintPath>..\..\..\..\..\..\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

To workaround this (until a better solution) I used subst command to create a virtual drive which points to a new location of the Packages folder:

subst N: C:\Development\NuGet\Packages

Now when adding a new NuGet package, the project reference use its absolute location:

<HintPath>N:\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

Note:

  1. Such a virtual drive will be deleted after restart, so make sure you handle it
  2. Don't forget to replace existing references in project files.
frankhommers
  • 694
  • 7
  • 20
Kamarey
  • 10,002
  • 6
  • 54
  • 68
  • Is it still the case today? I mean we cant use absoulute location for new added packages? this virtual drive solution looks cumbersome to me – Emil Nov 17 '16 at 10:35
  • Yep, still a case as nothing changed – Kamarey Dec 27 '16 at 11:42
  • 2
    I actually prefer a relative path - that way there's no conflict in source control if different developers have different root locations for the code. – jbyrd Aug 10 '17 at 16:36
  • I wonder why you can't do `$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll` instead of using `subst` – Vinod Srivastav Aug 21 '19 at 11:59
  • I wanted all packages to be in the single place, not per solution – Kamarey Sep 01 '19 at 06:10
5

The most consistent way is by using nuget config to explicitly set the config:

nuget config -set repositoryPath=c:\packages -configfile c:\my.config

https://docs.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior#changing-config-settings

yeerk
  • 1,550
  • 12
  • 14
4

Just updating with Nuget 2.8.3. To change the location of installed packages , I enabled package restore from right clicking solution. Edited NuGet.Config and added these lines :

  <config>
    <add key="repositorypath" value="..\Core\Packages" />
  </config>

Then rebuilt the solution, it downloaded all packages to my desired folder and updated references automatically.

amarnath chatterjee
  • 1,885
  • 14
  • 14
1
  1. Create nuget.config in same directory where your solution file is, with following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="packages" />
  </config>
</configuration>

'packages' will be the folder where all packages will be restored.

  1. Close Visual studio solution and open it again.
TarmoPikaro
  • 3,568
  • 1
  • 32
  • 42
0

If you're using Visual Studio 2019 and NuGet version 4 (or above), you may change the path by editing the NuGet.config file.

The NuGet.config file is in C:\Users%USER_NAME%\AppData\Roaming\NuGet

Add "globalPackagesFolder" and "repositoryPath" keys to the config file. Set the values that you wanted.

Here's an example

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="Microsoft Visual Studio Offline Packages" value="C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\" />
  </packageSources>
  <config>
    <add key="globalPackagesFolder" value="E:\.packages" />
    <add key="repositoryPath" value="E:\.nuget" />
  </config>
</configuration>
JeeShen Lee
  • 2,682
  • 4
  • 31
  • 54