Why are there similar Nuget package folders in .nuget\Packages directory? - nuget

Under c:\Users\<USER NAME>\.nuget\packages\ directory, there are some folders looks similar, for example:
System.IO.FileSystem.4.3.0
system.io.filesystem (and there are sub-folder "4.3.0" under it)
See attached figure.
My question: why are there similar Nuget package folders in .nuget\Packages directory? Can I delete one of them?

Possibly you used an old version of NuGet or Visual Studio on your machine, which used the old format. The other option is that you have a nuget.config that forces that solution packages folder to be your user profile's global packages folder. I really don't recommend this.
Maybe starting with NuGet 3.0 (Visual Studio 2015), NuGet uses the tolower(packageid)\tolower(packageversion)\ folder structure. I'm too lazy to test old versions to validate that earlier versions used something different. Or maybe NuGet has always used the same format for the global packages folder, making the packages.config answer the only possibility. But I really think that lowercase normalisation was something that was added and didn't always exist.
projects that use packages.config have always used the unmodified PackageId.PackageVersion format in the solution packages folder. I believe it was deemed too risky as a breaking change that some customers depend on to change in the solution packages folder. So, if anyone had the misguided idea that they could save disk space by making all their solutions share the same packages folder by using the same one for all solutions, and the folder they used is the global packages folder, then the two different parts of NuGet which intentially use different folder naming conventions, will write to the same directory.
As long as you're not in the middle of a build, it's always safe to delete folders in any packages folder (global packages, as your question is about, or a solution packages folder). If a project needs a package that was deleted, NuGet will download it again, so if you have a download quota, or a slow internet connection, maybe be mindful. Otherwise you can be as liberal with deleting folders as you like. Just make sure to delete the entire folder. There's only one file NuGet looks for when restoring, so if you delete other files but leave that one, NuGet will think it's downloaded and extracted properly, but your machine will behave differently to other machines.

Related

Why does NuGet store packages in C:\Users\<UserName>\.nuget\packages?

I understand that it is now possible to configure a global package directory for all projects but I noticed that NuGet also puts files in my home directory. Is it possible to configure a single repo which will be used for all projects?
NuGet introduced a new way of package management in for project.json (now deprecated) and PackageReference-based projects (default .NET Core, .NET Standard).
Instead of creating a solution-local packages folder to which all packages are downloaded and extracted (alt: repositoryPath location in NuGet.Config override), all packages are downloaded to a global location (controlled by globalPackagesFolder in NuGet.Config) which is defaulted to %userprofile%\.nuget\packages (~/.nuget/packages on linux/Mac).
The idea is that you don't have to download packages multiple times and the csproj files no longer reference all individual files but just the package. .NET Core projects also do not need to copy the NuGet packages' assets because the generated .runtimeconfig.json file specifies the location of the global cache to look up the packages at runtime, so builds can be a little bit faster.
See this question, I believe everything will be clear after that
Setting up a common nuget packages folder for all solutions when some projects are included in multiple solutions

Using NuGet when developing several dependent projects locally

The problem I want to solve is how to work with NuGet on several local projects that depend on each other without having to copy files around manually and have all sorts of dll issues as a result.
Today my projects (c#) are not using NuGet (working to move them to NuGet), and the way it works is that when working locally all projects build outputs to a "shared bin folder" and all reference from there, so that you alway see the right binaries you are building locally.
On the build server, through some games in the csproj files, projects reference a non-shared bin and get the dependencies there.
How can I achieve the same effect with NuGet? What is the right way to work locally without having to copy dll around manually? (And of course keep the ability to build in the server by getting everything using NuGet normally)
Is there a way to get packages to one bin folder with NuGet or at least folders without version numbers so I can just build and reference from there? And is this even wise?
Assume the latest NuGet, VS versions as required.
Thanks a lot for your help,
Roy.

nuget command line update doesn't detect all packages.config which need to be updated

We have a build step that installs and updates the nuget packages in a solution on out build server (TeamCity). Recently this has stopped doing the updates correctly. I have investigated this and found that the problem seems to be that the update command in nuget is not updating all the projects in the soltution. I can replicate this on my local machine.
When I run this command:
.nuget\NuGet.exe update Our.Company.sln -Source http:/ourTcServer:8888/guestAuth/app/nuget/v1/FeedService.svc -RepositoryPath packages -verbosity detailed
I get this a list of 10 projects it is going to update
Found 10 projects with a packages.config file. (
Company.Project1.csproj,
Company.Project2.csproj,
Company.Project3.csproj,
Company.Project4.csproj,
Company.Project4.SubProject1.csproj,
Company.Project4.SubProject2.csproj,
Company.Project1.SubProject1.csproj,
Company.Project1.SubProject2.csproj,
Company.Project2.SubProject1.csproj,
Company.Project2.SubProject1.FurtherSubProject1.csproj)
However the solution contains 13 projects and these all contain packages.config files and as far as I can tell are no different to any of the other projects. The projects are a single project and its subprojects and our projects directory structure matches the projects names (so project1.subproject1 implies that subproject1 is in a folder inside project1) in case that is important. The projects with the issue are all in a project which has the specific names like :
Company.Something.SomethingElse.Routing
Company.Something.SomethingElse.Routing.Tests
Company.Something.SomethingElse.Routing.Tests.Specifications
In case the routing part of the name causes a problem (we had a problem before using the word Resources at the end of our package name)
We have 50+ solutions that all use the same build configuration and steps and it works fine for all of them. This solution seems to be the only one which is not updating correctly.
Does anyone know why this might be the case? Or does anyone know what the code that finds packages in a solution does which might cause it not to find some packages.config files? Or anything that might help track down this issue?
Ok so the issue was that we had renamed some of our projects and so the .csproj files and had not removed to old, unused project files and nuget has a piece of code which finds the projectfile into which it it going to update the references of the updated packages. It does this by finding all the files which are .csproj (or whatever project file flavour you are using) in the same directory as the packages.config. If this does not result in exactly 1 file then it throws an exception, which is subsequently caught and ignored and nothing is logged, so you are non the wiser.
Hopefully this will help someone else in the future. Maybe me.
I found that the problem I ran into was that my projects were not in the same directory tree of the solution.
The nuget.exe update command when given solution file searches for packages.config files using the solution directory as the starting point instead of looking at each project file in the solution.
From the nuget code on GitHub:
string[] packagesConfigFiles = Directory.GetFiles(
solutionDir, "*.config", SearchOption.AllDirectories);
You can see that they are just looking for *.config files starting in the solution directory.
My projects and solutions are organized like this:
/Libraries/Shared/Shared.csproj
/Programs/NTService/NTService.csproj
/Programs/NTService.sln
In this case, if I run update on the NTService.sln file it will only update the NTService.csproj references because it is in the same directory tree as the NTService.sln file.
Since it just looks at all packages in the whole tree, I just put a solution file at the root of my repository and then run the update on that. It doesn't matter what projects are in that solution file.

Get current version of package outside of Visual Studio

We are migrating over to using packages and NuGet for managing our dependencies on 3rd party components. This works well when referencing packages from within Visual Studio or building on the build server via msbuild.
However there are a number of files that we would like to access in our build scripts and installers. Previously these would be in source control with a well known path, now as the version of the package that we are consuming changes so the path to the package and hence the files is changing.
Is there a simple way I can get the path to a given package? The best solution I currently have is to search for all packages.config files and extract the package version from them.
Examples of the files that we need to access are
The NUnit console executable from the NUnit.Runners package for running unit tests.
License files from various packages that we redistribute with our installer.
Using the packages.config file is a pretty good solution. NuGet itself uses two approaches:
Reading the package information from the packages.config and using that to resolve to the packages path.
Enumerating all the directories in the packages directory.
You could use NuGet.Core to do either of the above if you do not want to write the code yourself. The classes that can be used are the DefaultPackagePathResolver, the PackageReferenceFile and LocalPackageRepository or SharedPackageRepository.
One problem with the second approach is that sometimes NuGet may occasionally leave behind NuGet packages that are not necessarily referenced by a project. In that case looking at the package directories may give you the incorrect information.
The only other approach I can think of might be to read the project files looking for the assembly references. Although that would not work for a solution level package such as NUnit.Runners.

How to best use NuGet for source file deployment

I would like to use NuGet packages for building packages for core helper libraries which I would like to add as source files into other projects. I want to use source files instead of libraries for several reasons, the main one being that I need them in SharePoint Projects, which is on the one hand much easier to deploy than additional libraries, and on the other hand helps to reduce version conflicts.
I know that I can add the source files as content to NuGet Packages, which would install them with the package. But this won't work together with package restore, and I don't want to have these files checked into source control in all projects.
Is it somehow possible to make a NuGet package which doesn't copy the files to the project, but instead adds file links, which point back to the file in the package folder, to the project? I think this approach would solve my use case.
Thanks
pascal
It is possible to add linked files with the use of PowerShell scripts, for example with this NuGet script: http://www.nuget.org/packages/Baseclass.Contrib.Nuget.Linked/