Change NuGet package folders used by Visual Studio 2017 - nuget

There is no more packages solution folder in any csproj or project.json-based .NET Core project.
NuGet CLI gets the list of used cache folders:
nuget locals all -list
Response:
http-cache: C:\Users\<foo>\AppData\Local\NuGet\v3-cache
global-packages: C:\Users\<foo>\.nuget\packages\
temp: C:\Users\<foo>\AppData\Local\Temp\NuGetScratch
How to change or override these locations?

Cache locations
Solution-local packages folders are no longer exist for .NET Core and Visual Studio 2017.
NuGet is now fully integrated into MSBuild:
Solution-local packages folders are no longer used – Packages are now
resolved against the user’s cache at %userdata%.nuget, rather than a
solution specific packages folder. This makes PackageReference perform
faster and consume less disk space by using a shared folder of
packages on your workstation.
NuGet 4.0+ uses at least two global package locations:
User-specific: %userprofile%\.nuget\packages\
Machine-wide: %ProgramFiles(x86)%\Microsoft SDKs\NuGetPackages\"
You can list all user-specific folders using the following console command:
nuget locals all -list
Notice that the machine-wide folder isn't listed there. However, it is defined at Visual Studio settings:
Options -> NuGet Package Manager -> Package Sources
Configuration files
NuGet.config files are located here:
User-specific: %APPDATA%\NuGet\
Machine-wide: %ProgramFiles(x86)%\NuGet\Config\
It is possible to change and override NuGet settings at many levels:
project
solution
user
machine
And even more! Read more about NuGet.config hierarchical priority ordering here: How settings are applied.
For example, globalPackagesFolder parameter changes a package cache location. Look at this NuGet.config example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<clear />
<add key="globalPackagesFolder" value="c:\packages" />
</config>
</configuration>

From the MS docs:
global‑packages
Windows: %userprofile%\.nuget\packages
Mac/Linux: ~/.nuget/packages
Override using the NUGET_PACKAGES environment variable, the globalPackagesFolder or repositoryPath configuration settings (when using PackageReference and packages.config, respectively), or the RestorePackagesPath MSBuild property (MSBuild only). The environment variable takes precedence over the configuration setting.

Copying the .nuget folder (c:\users{username}.nuget) from the development pc which has an internet connection and the updated packages, to the pc which doesn't have the internet connection also worked for me.

Related

Is there a way to configure NuGet to ignore unavailable package sources?

When developing in Visual Studio 2017, I use a combination of the standard NuGet package source, and package sources from the company I work for.
To access those company package sources, I have to connect to our company VPN.
Unfortunately, this means I have to always be connected to our company VPN, no matter what I'm developing, because otherwise NuGet gives me this:
Exception 'System.AggregateException' thrown when trying to add source 'http://[one of my company's package sources]'. Please verify all your online package sources are available.
One or more errors occurred.
Unable to load the service index for source http://[one of my company's package sources].
An error occurred while sending the request.
The remote name could not be resolved: '[one of my company's package sources]'
This would make sense if I'm trying to use a package only hosted on my company's servers. But even if I specifically set the Package source dropdown to nuget.org, I get this error.
There's an issue to fix it, but it's two years old and shows no signs of activity: install fails when a nuget Source is unavailable even when this is not the selected Source #2614
So, is there a way somehow to configure NuGet to ignore missing package sources?
As explained in this answer, the behavior of Visual Studio 2017 is by design, but maybe you can use a custom nuget.config as a workaround (also explained in that answer).
Here's how to config NuGet to ignore some sources.
If you have all your non-company code in a single folder structure, then in the root you can put a nuget.config file that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<disabledPackageSources>
<add key="My Company's NuGet Source" value="true" />
</disabledPackageSources>
</configuration>
If you're not sure what that key should be, run nuget sources from the command line:
>nuget sources
Registered Sources:
1. nuget.org [Enabled]
https://api.nuget.org/v3/index.json
2. My Company's NuGet Source [Disabled]
https://path/to/the/nuget
3. Microsoft Visual Studio Offline Packages [Enabled]
C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
This is also a good way to verify that the nuget.config is being detected. The Disabled is from my nuget.config file; if I run nuget sources in my company code folder, number 2 shows as Enabled.
You can find full details about the structure of nuget.config here:
nuget.config reference

Why isn't there any packages folder in my .NET Core solution's containing folder?

Are packages now cached in a more shared location somewhere or what?
My solution folder is devoid of any packages folder:
Per project: References->Nuget dictates what packages are referenced and restored. But, as Eastrall mentioned, the packages folder is now global and located in your user folder: C:\Users\[YourUsername]\.nuget\packages
To force ./packages folder for Solution
To force download of packages folder to be a child of the solution folder for .NET Core projects, follow these steps:
Create a NuGet.Config file in the same directory as the .sln file.
Copy the following contents into the NuGet.Config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value=".\packages" />
</config>
</configuration>
Configure NuGet to download missing packages by:
3.1. In Visual Studio: Tools -> Options
3.2. Filter by nuget (top left in dialog). Select General
3.3. Ensure Allow NuGet to download missing packages is checked
Close and re-open the solution. NuGet will download the required packages.
Note: the NuGet.Config configuration can also be achieved by executing the following command from the NuGet Package Manager Console (Tools -> NuGet Package Manager -> Package Manager Console):
PM> nuget config -set globalPackagesFolder=.\packages -configfile "$(pwd)\NuGet.Config"
You still have packages folder in your .NET Core solution, but the global packages are located at: C:\Users\[YourUsername]\.nuget\packages
You can check out a question I asked to see if the answers do you any good.
How do I include NuGet packages in my solution for .Net Core projects?
You can get that packages folder back, but you might not be happy with the results, since .Net Core projects rely on so many NuGet packages. Mine is hovering around 1 GB.
https://learn.microsoft.com/en-us/nuget/schema/nuget-config-file#config-section

Use solution relative packages folder with NuGet and project.json

I have a solution with a packages folder checked into source control. I changed some of the projects to use a project.json file rather than packages.config for defining dependencies. The projects are all normal .csproj projects, not DNX .xproj projects. Everything seemed to be working correctly however after updating a package I noticed that the new version wasn't added to the solution's packages folder. Instead it was added to NuGet's new shared packages folder in the user profile folder.
So the question is, how do I get NuGet to use the solution's packages folder rather than the shared folder?
Approaches I've tried so far without success:
Adding global.json file in the solution folder specifying "packages": "packages"
Setting <add key="disableSourceControlIntegration" value="false" /> in .nuget\nuget.config
NuGet 3.2 added support for specifying the shared global packages folder using an environment variable, NUGET_PACKAGES. You can set the full path to an alternative global packages folder, however I discovered that if you simply set the variable to "packages" then the NuGet tools in Visual Studio will treat it as a relative path under your solution folder. That allowed me to install and restore NuGet packages using the solution's packages folder.
Unfortunately building projects then gave me errors in Microsoft.NuGet.targets, unable to locate NuGet packages. The NugetPackagesDirectory property in msbuild doesn't seem to getting set. To work around this I added the following lines in to the C:\Program Files (x86)\MSBuild\Microsoft\NuGet\Microsoft.NuGet.props file:
<PropertyGroup Condition="'$(NugetPackagesDirectory)' == ''">
<NugetPackagesDirectory>$(SolutionDir)packages</NugetPackagesDirectory>
</PropertyGroup>
This will affect all solutions on the machine so an alternative would be to add those same lines in each project file or into a custom props file in the solution which you import into each project. This may also be needed for build servers too.
Although this works, the drawback is that the packages folder has a different structure, packages\<package_name>\<version>\ compared to packages\<package_name>.<version>\, and old or unused versions of packages aren't deleted after they're updated or uninstalled. Manually clearing the packages directory and then restoring required packages after any changes will achieve the same thing.
Personally this feels really hacky as it requires setting global settings for something which should be set on a per solution basis. NuGet is going to be updated at some point to support per solution package directories with project.json but in the meantime this you can use the above work around, or just stick with packages.config for the time being.

Can't specify nuget package folder location [duplicate]

We use a custom location for our packages folder which we specify in a nuget.config file in the same folder as our solution:
<settings>
<repositoryPath>..\..\lib\packages</repositoryPath>
</settings>
Visual Studio 2013 picks this up fine and the NuGet package manager installs packages into the specified folder, lists installed packages correctly, etc.
In Visual Studio 2015 RC the NuGet package manager pops up the "Some packages are missing from this solution, click here to restore" message and if I click the button it creates a new packages folder in the same folder as the solution rather than using the location specified in the nuget.config. Installing a completely new package also puts it into a packages folder under the solution folder rather than the specified one.
How do I get Visual Studio 2015 RC to respect the repository path specified in the nuget.config?
Make sure your nuget.config is configured like this:
<configuration>
<config>
<add key="repositoryPath" value="..\..\lib\packages" />
</config>
</configuration>
I filed this bug with NuGet: https://github.com/NuGet/Home/issues/626
A fix has been made but I'm not sure when it will be released.

NuGet Package Restore doesn't work

I have added a NuGet package to my solution and enabled package restore on the solution. This correctly created the .nuget folder with targets file etc.
The NuGet package is actually another project which becomes a dependency in the solution. Initially I added this package to the solution manually.
To Test this NuGet feature, I deleted the folder underneath the packages folder.
At that point I then get compiler errors obviously because other dependent projects are reliant on the project that has just been removed.
When I build the solution, I'm expecting NuGet to go and download the NuGet packages that it requires is this is set to Enable Package Restore, and then build successfully as all other dependent projects can now build.
However, I see no evidence of the NuGet package from being downloaded in the output, and the build errors remain the same as if the project hasn't been downloaded.
Can anyone confirm whether there is something I am missing or am doing wrong here?
To my knowledge deleting packages under the packages folder should be restored by NuGet's package restore feature.
It would be helpful to:
See the actual build error.
Know which packages you are trying to restore.
Some packages, such as ours, rely on .targets files which have issues when being used in package restore.
Make sure that NuGet.Config in your solution folder has "packageRestore" option enabled:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
</configuration>
Also it should be enabled globally in "C:\Users\%UserName%\Application Data\NuGet\NuGet.Config" (it can be set from within VS, Tools->Options->Package Manager.
Also note that there's another approach for restoring package since NuGet 2.7 - "Automatic Package Restore". See doc for more info: http://docs.nuget.org/docs/reference/package-restore and http://docs.nuget.org/docs/workflows/migrating-to-automatic-package-restore