What does _._ mean in a package? - nuget

I suppose this has been asked many times, but I cant find it.
But what dies . mean in a package lib folder?

They are placeholder files to denote an empty directory. Empty directories are often not well-supported in ZIPs so a file with that name is placed in there to ensure the directory is created.
This is important because the existence of an "empty" net46 folder means that the package supports .NET Framework 4.6, but does not require any assemblies (DLLs) in order to run on that version of .NET. This is most likely because the implementation of the package is in the GAC.
(Eilon Lipton, https://github.com/aspnet/Home/issues/744#issuecomment-123411563)

Related

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

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.

What do _._ files mean in nuget packages?

While looking at the contents of a Nuget package I came across the following file named:
_._
Shown by the Image below:
What does this file mean or do in nuget packages?
They are placeholder files to denote an empty directory.
Empty directories are often not well-supported in ZIPs so a file with that name is placed in there to ensure the directory is created.
From this link
They are placeholder files to denote an empty directory. Empty directories are often not well-supported in ZIPs so a file with that name is placed in there to ensure the directory is created.
This is important because the existence of an "empty" net46 folder
means that the package supports .NET Framework 4.6, but does not
require any assemblies (DLLs) in order to run on that version of .NET.
This is most likely because the implementation of the package is in
the GAC.

How do I get a binary NuGet package with one csproj's assembly but a corresponding source package with two csproj's sources?

Using the really easy to follow instructions for building a NuGet package for an assembly with an associated package of sources for the symbol server, found here on David Ebbo's blog "The easy way to publish NuGet packages with sources" I have indeed created a pair of packages: binary and sources.
However, the sources package is incomplete and the reason is that the sources come from two class library .csproj and I used ILMerge to combine the results of the second into the first. (*) So, using the minimal .nuspec described in this post and pointing nuget.exe at the .csproj for the "main" library, the binary package is fine, but of course the sources package only has sources for the "main" library, not also for the library that was ILMerged into the "main" library.
How do I fix this (and get the sources for both projects included in the symbol package but only the binary for the "main" project in the binary package)?
FYI, the actual nuget.exe command line was: nuget pack CommandLineLexing.csproj -Build -Symbols -Properties Configuration=Release.
(*) The reason I'm doing this, in case you're interested, is that the second library is a cut down version of my accumulated "C# utilities" library - you know, a bunch of extension methods and other helpers - cut down so it only has the bare minimum needed for this particular project. And so, since it is cut down, I don't want there to be separate assembly for it which might eventually get confused with the full assembly (having the same name, and not a strong name). So I used ILMerge to put the utilities methods into the main assembly (and also mark them internal).
Not going to be easy I'm afraid.
NuGet symbol packages are simply your regular package, with pdbs, augmented with source files.
Assuming you already know you can get a merged PDB with ILMerge/ILRepack (/debug), that part is probably working file, I'm assuming your issue is that only the source files from the current project gets included.
You could simply post-process your symbol.nupkg (which is a zip), and include the source files from your other (merged) project in the src folder (you can even try that manually).
Though if you run srctool.exe -r MyMergedAssembly.pdb, you'll see different root paths, where usually (for a non-merged project) they all have a common prefix.
It may work, if SymbolSource copes with having multiple path prefixes in your PDB, that I haven't tried.
I also failed to find any documentation irt to their processing of symbol packages. We can assume they use pdbstr.exe tool to update the PDB srcsrv section of the PDB file to redirect the symbol loading to their website, but one can only tell if they support multiple roots by testing it.
If you upload your augmented symbol package to symbolsource, you can download the updated PDB using a URL similar to http://srv.symbolsource.org/pdb/Public/Castle.Core.pdb/4C81FC30DF584853B9869EAB2FA7D9891/Castle.Core.pd_ (then unzip it to a pdb file)
Then you can use both srctool.exe file.pdb and pdbstr.exe -r -s:srcsrv -p:file.pdb to verify their work.

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.

NuGet Packaging and referencing dll's

Background: I have two assemblies called "A" and "B". ""A" references "B". "A" also references some additional dll's (Microsoft.Enterprise Library.Data and Microsoft Enterprise Library.Common ) that I think should be packaged in the nupkg.
I believe my nupkg package should contain the assembly output from "A", "B" and the two "Microsoft Enterprise" assemblies so that when someone installs my package it will give them a direct reference to the Assembly "A" and the other three assemblies would be available (but not directly referenced, so that their app would run. What is the correct way of packaging the non references dlls?
Attempt #1: Packing all required dll's in a \net35 folder
According to the NuGet documentation regarding the "references" element "If this element is omitted, then the usual behavior applies, which is to reference every assembly in the lib folder."
So, I assume that by using this element it will only include the assemblies specified as references. This does not seem to be the case if I also use a "file" element <file src=*.dll" target="lib\net35" />. If I have an element like this that copies all dll's to the package it results in the assembly that implements this package to reference ALL the assemblies in the \net35 directory. This is not what I want to do. I expected some magic that only the assembly specified in "references" would be an actual be referenced and all the others would remain in the exploded \packages folder and the app would work since all the dlls are located in the same directory. Maybe I'm incorrect....
Attempt #2 Adding as content to project
If I place the unreferenced assemblies into \content\lib instead of lib\net35 when packaged this creates a \lib folder in the project and directly dumps the \content\lib dlls into that project which then forces us to check them into source control. This works, compiles and runs as I want but, I really don't want these stored in the \lib folder of the project.
I am looking for a solution where the project gets the references to "A" and can still run with the to other required assemblies co-located but not directly referenced. It seems like Attempt #1 is the correct path but maybe there is a bug?
FYI, I entered this as a issue with NuGet directly to see it that team has an answer as well.
This was a bug introduced in Nuget 2.1 and was later fixed in Nuget versions 2.2 which was released in December 2012.
Using Attempt #1 in original posting now works correctly.
I don't think your "Attempt 1" is going to work in practice. If you only reference "A". when you build your package, only "A" will be copied (by default) to the output directory. Then, when you distribute the application, only "A" will exist causing errors.
You should have references to all DLLs to make your application run (or come up with another solution that will automatically copy the referenced DLLs to the output directory, but I'm not sure there is much value in not specifying the reference directly). Since you only have a few DLLs, it is probably best to just leave out the references section so that all of the DLLs are referenced automatically from the lib folder.