config and PackageReference. And for PackageReference format, the packages are stored in C:\Users\xxx\. nuget\packages .
Simply copy existing packages. config file to your new project. Include this file into the project. Then follow to Package Manager Console and execute Update-Package -reinstall command.
nuget folder is used as a cache for packages downloaded to speed up project restore and compilation. It can safely be removed. Worst case, it will have to download the packages again in the future.
I have a similar situation with external and internal package sources with projects referenced in more than one solution. I just got this working with one of our code bases today and it seems to be working with the developer workstations and our build server. The below process has this scenario in mind (although it shouldn't be hard to adapt to have the common packages folder else where).
This process is a bit easier now than when I originally tackled this and thought it was time to update this. In general, the process is the same just with less steps. The result is a process that solves or provides the following:
There are some potential downsides to be aware of (I haven't experience them yet, YMMV). See Benol's answer and comments below.
You will want to create a NuGet.Config file in the root of the \Solutions\ folder. Make sure this is a UTF-8 encoded file that you create, if you are not sure how to do this, use Visual Studio's File->New->File menu and then pick the XML File template. Add to NuGet.Config the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
For the repositoryPath setting, you can specify an absolute path or relative path (recommended) using the $ token. The $ token is based on where the NuGet.Config is located (The $ token is actually relative to one level below the location of the NuGet.Config). So, if I have \Solutions\NuGet.Config and I want \Solutions\Packages I would need to specify $\..\Packages as the value.
Next, you will want to add a Solution Folder to you solution called something like "NuGet" (Right-Click on your solution, Add->New Solution Folder). Solution Folders are virtual folders that only exist in the Visual Studio solution and will not create an actual folder on the drive (and you can reference files from anywhere). Right-Click on your "NuGet" solution folder and then Add->Existing Item and select \Solutions\NuGet.Config.
The reason we are doing this is so that it is visible in the solution and should help with making sure it is properly committed to your source code control. You may want to do this step for each solution in your codebase that is participating with your shared projects.
By placing the NuGet.Config file in \Solutions\ above any .sln files, we are taking advantage of the fact that NuGet will recursively navigate the folder structure upwards from the "current working directory" looking for a NuGet.Config file to use. The "current working directory" means a couple of different things here, one is the execution path of NuGet.exe and the other is the location of the .sln file.
First, I highly recommend you go through each of your solution folders and delete any \Packages\ folders that exist (you'll need to close Visual Studio first). This makes it easier to see where NuGet is placing your newly configured \Packages\ folder and ensures that any links to wrong \Packages\ folder will fail and can then be fixed.
Open your solution in Visual Studio and kick off a Rebuild All. Ignore all of the build errors you will receive, this is expected at this point. This should kick off the NuGet package restore feature at the start of the build process however. Verify that your \Solutions\Packages\ folder has been created in the spot you want. If it hasn't, review your configuration.
Now, for each project in your solution you will want to:
Once all of your .csproj files have been updated, kick off another Rebuild All and you should have no more build errors about missing references. At this point you are done, and now have NuGet configured to use a shared Packages folder.
First off the thing to keep in mind is that nuget.config does not control all of the path settings in the nuget package system. This was particularly confusing to figure out. Specifically, the issue is that msbuild and Visual Studio (calling msbuild) do not use the path in nuget.config but rather are overriding it in the nuget.targets file.
First, I would go through your solution's folder and remove all \packages\ folders that exist. This will help ensure that all packages are visibly installing into the correct folder and to help discover any bad path references throughout your solutions. Next, I would make sure you have the latest nuget Visual Studio extension installed. I would also make sure you have the latest nuget.exe installed into each solution. Open a command prompt and go into each $(SolutionDir)\ .nuget\ folder and execute the following command:
nuget update -self
Open each $(SolutionDir)\ .nuget\NuGet.Config and add the following inside the <configuration> section:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
Note: You can use an absolute path or a relative path. Keep in mind, if you are using a relative path with $ that it is relative to one level below the location of the NuGet.Config (believe this is a bug).
Open each $(SolutionDir)\ .nuget\NuGet.targets and modify the following section (note that for non-Windows there is another section below it):
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
<!-- Windows specific commands -->
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
<PackagesDir>$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
</PropertyGroup>
Update PackagesDir to be
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
Note: The GetFullPath will resolve our relative path into an absolute path.
Open a command prompt and goto each $(SolutionDir)\ .nuget and execute the following command:
nuget restore ..\YourSolution.sln
At this point, you should have a single \packages\ folder in your common location and none within any of your solution folders. If not, then verify your paths.
Open every .csproj file in a text editor and find any references to \packages and update them to the correct path. Most of these will be <HintPath> references, but not all of them. For example, WebGrease and Microsoft.Bcl.Build will have separate path settings that will need to be updated.
Open your solution in Visual Studio and kick off a build. If it complains about missing packages that need to be restored, don't assume that the package is missing and needs to be restored (error can be misleading). It could be a bad path in one of your .csproj files. Check that first before restoring the package.
If you have already verified that the paths in your .csproj files are correct, then you have two options to try. If this is the result of updating your code from source code control then you can try checking out a clean copy and then building that. This worked for one of our developers and I think there was an artifact in the .suo file or something similar. The other option is to manually force a package restore using the command line in the .nuget folder of the solution in question:
nuget restore ..\YourSolution.sln
Instead of setting common package location for all projects, it is also possible to change HintPath in project as follow:
<HintPath>$(SolutionDir)\packages\EntityFramework.6.1.0\lib\net40\EntityFramework.dll</HintPath>
In most cases there in shared project will be only few packages, so you can easily change it.
I think it is better solution, when you branching code, when setting common repo, you must change relative path, in this solution you don't need to do this.
My experience trying this with the latest version of NuGet (2.7) and VS2012:
In my case, I wanted to put all packages in .packages
, so my NuGet.Config looked like below.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositorypath" value=".packages" />
</config>
</configuration>
Note that there are a few 'strange' things that can happen, but I think they're bearable:
Disclaimer: I just tried this today, I don't have any long term experience to back it up!
I have NuGet version 2.8.50926 with VS 2013. You don't need to use multiple nuget.config files, or use complex directory structures. Just modify the default file located here:
%APPDATA%\Roaming\NuGet\NuGet.Config
Here is the content of my file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="C:\Projects\nugetpackages" />
</config>
<activePackageSource>
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
</activePackageSource>
</configuration>
So all packages go to the "C:\Projects\nugetpackages" folder, no matter where the solution is.
In all your solutions, just delete existing "packages" folders. Then build your solution, and NuGet will automatically restore the missing packages in the new, centralized directory you specified.
Already there is no need to modify nuget.targets. It has been fixed in nuget 2.8 (http://nuget.codeplex.com/workitem/2921). You only need to set repositorypath.
From Visual Studio 2013 Update 4 and Nugget Package Manager version > 2.8.5...
Create nuget.config file in root of repository.
file content:
<configuration>
<config>
<add key="repositoryPath" value="packages" />
</config>
<packageSources>
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
</packageSources>
</configuration>
This will cause that all packages will go to packages folder on level of your's nuget.config file.
Now you can go for each .sln nuget console with command 'update-package -reinstall'
If you have like multiple repository at the same level and what to share the same package folder across them try use way to go one folder up.
<add key="repositoryPath" value="..\packages" />
But this way you cause that nuget packages reference csproj is pointing one folder up outside you repositorys path.
I've concocted a NuGet package that transparently converts all NuGet references in a project to a $(SolutionDir)-relative format. It does so using build-time XSLT transform, so you don't need to hack your project file by hand. You can update your packages freely, it will break nothing.
https://www.nuget.org/packages/NugetRelativeRefs
Or you if you use Visual Studio 2015 Update 3, you can just migrate your package references to project.json
form as described here:
https://oren.codes/2016/02/08/project-json-all-the-things
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With