English 中文(简体)
Is it possible to change the location of packages for NuGet?
原标题:

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?

最佳回答

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:	hePathToMyPackagesFolder" />
  </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.

问题回答
  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="..ExtLibsPackages" />
  </config>
  ... 
</configuration>

this did WORK for me:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..ExtLibsPackages</repositoryPath>
</settings>

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

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

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.862libNET40Autofac.Configuration.dll</HintPath>
</Reference>

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

From https://learn.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%.nugetpackages (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.

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>....ExtLibsPackages</repositoryPath>
</configuration>

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

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 AppDataRoamingNuGet 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

Visual Studio 2019 and Nuget 5.9.*

  1. Open %AppData%NuGet folder, open existing NuGet.Config file. Edit repositoryPath key and set new destination.
 <config>
  <add key="repositoryPath" value="D:.nugetpackages" />
  </config>
  1. In environment variables edit system variable NUGET_PACKAGES and set new destination

enter image description here

  1. Restart VS. No need to put nuget.config file in every solution.

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

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.

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.

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>............SomeAssemblylib
et45SomeAssembly.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:DevelopmentNuGetPackages

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

<HintPath>N:SomeAssemblylib
et45SomeAssembly.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.

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://learn.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior#changing-config-settings

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="..CorePackages" />
  </config>

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

  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.

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%AppDataRoamingNuGet

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 SDKsNuGetPackages" />
  </packageSources>
  <config>
    <add key="globalPackagesFolder" value="E:.packages" />
    <add key="repositoryPath" value="E:.nuget" />
  </config>
</configuration>

While using Visual Studio 2019 and NuGet v4 or later I was looking for a solution that doesn t involve changing the machine-level or user-level config and doesn t use an absolute path.

According to the NuGet Documentation, the value can be overridden by a nuget.config file placed in the current folder (e.g. solution folder) or any folder up to the drive root. Note that NuGet 3.3 and earlier was expecting the nuget.config files to be placed in a .nuget subfolder. This got me at first, as my setup was originally targeting older versions, so I deleted this subfolder.

I ended up with a nuget.config file placed in my Dev folder (which contains subfolders for the different VS solutions):

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

With this setup, all solutions/projects under my Dev folder install their packages in a folder named installed_packages located at the same level as the nuget.config file.

Finally, note that repositoryPath is used by projects that make use of packages.config, whereas globalPackagesFolder is used by projects that make use of PackageReference.

Create a nuget.config file in the same directory where your solution file is located with the following content, and restart the visual studio. (I test it with VS2022) [./packages - Replace it with your package path]

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <settings>
  <repositoryPath>./packages</repositoryPath>
 </settings>
</configuration>



    




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签