Create nuget package with multiple DLLs - nuget

Let's say I have a project with this structure:
MyLibrary\
MyLibrary.sln
MyLibrary.Core\
MyLibrary.Core.csproj
MyLibrary.Extensions\
MyLibrary.Extensions.csproj
MyLibrary.Tests\
MyLibrary.Tests.csproj
I want to create a single NuGet package which packages MyLibrary.Core.dll and MyLibrary.Extensions.dll. I can't seem to figure out how to get NuGet to do this. I've tried building a spec file manually and I've tried building one using "nuget spec MyLibrary.Core.csproj". I've tried adding all of the DLLs to a lib/ folder which I understand to be the convention-based mechanism for adding DLLs to the package. In every case I can get the MyLibary.Core.dll to get into the package but the MyLibrary.Extensions.dll does not end up packaged along with it.
TLDR: What is the best practice for creating a NuGet package with multiple projects / assemblies? Is there a tutorial out there that focuses on this? The tutorials I've found all focus on simple single-project demos.

You'll run NuGet on a single project (or nuspec file), but it supports pointers to other projects via the file element. This element uses the names of your project's References, so you avoid having to a) find the location of other project files, and b) copy files to a particular place as a post-build step.
Supposing you have a nuspec file for MyLibrary.Core.csproj, and it references MyLibrary.Extensions and MyLibrary.Tests such that they end up in the bin directory after a build:
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
...
</metadata>
<files>
<file src="bin\Release\MyLibrary.Extensions.dll" target="lib\net40" />
<file src="bin\Release\MyLibrary.Tests.dll" target="lib\net40" />
</files>
</package>
With this setup, all of your references should end up in the appropriate place in the NuGet package. You still have the hard-coded 'Release' in there, but I'd wager most probably don't distribute NuGet packages of their debug builds anyway.

Did you generate a blank nuspec file with:
nuget spec
If you use that file and then put your dlls in a folder under it named lib, it will package them up.
I had a little trouble with trying to generate a nuspec file from a project or dll. Also, if you manually reference any files in the nuspec file, the conventions are not used. This is probably the problem with nuspecs generated from dlls or projects.
Also, if you are trying to run this from a build script that executes in a different folder, you can tell nuget the location of your .\lib folder via the -BasePath command line:
build\nuget.exe pack nuget\Company.Project.nuspec -BasePath nuget\

Have you tried NuGet Package Explorer? Might be the easiest way:
http://nuget.codeplex.com/releases/view/59864

It seems your problem is the same as this question: Why doesn't nuget include the referenced project when packing?. If so, you can use the -includereferencedprojects option (See http://docs.nuget.org/docs/reference/command-line-reference#Pack_Command).

I recently published a solution for this...
My solution enables automatic creation of NuGet packages when you build the solution where each package can contain multiple assemblies, references to both external NuGets and NuGets created during the same build and even include the source code for debugging.
In your case, all you will need to do is add a new class library project to your solution, reference the projects you want to package, then add a post build event.
You can find an article with a walk-through guide here
and the source code here.

i have some tutorial how i did it with windows and visual studio:
create local folder and call it packages like: c:/packages//lib - important to create another folder in folder call it lib and past there dll.
open nuget package explorer - https://npe.codeplex.com/downloads/get/clickOnce/NuGetPackageExplorer.application
the ui very intuitive just add dll and export it to /lib (for tutorial https://blog.zwezdin.com/2014/building-nuget-packages-with-gui-tool/ it in russian but see on pictures the flow it's about 3 clicks)
it will create nuspec file
open GIT BASH - https://git-for-windows.github.io/ and navigate to: cd c: => cd packages (the path of )
*maybe on windows you will need provide developer options for windows's linux stuff (https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/)
in GIT BASH enter command: nuget add -source [options]
where: : the full name of nuspec (include .nuspec)
and: the path of folder lib in folder (c:/packages//lib)
after the action ended successfully
in GIT BASH enter another command:
nuget pack .nuspec
not in this folder you have .nupkg file.
How to install a Nuget Package .nupkg file locally? - tutorial how to add it to visual studio.

I had the same problem and I decided to create Nuget which will allow to create other nugets from chosen project.
Package is deployed on the Nuget.org site. After referencing it in the project You need to add nuspeck file to the projects which should generate the projects.
Project with the required nuspeck file
Last thing which should be done by you is invoke command Create-Nuspec in Package Manager. Than the powershell module will take all libraries which are result of the build it will add also the required dependencies and create the nuget in the output directory.
Description about this package is placed here.

I had an issue when adding extra dlls references to a Nuget packages, and testing the package on a sample project, the extra dlls was not being added apparently, no matter the way that I create the Nuget Package.
Then I released that when you uninstall and install again a local Nuget Package with the same version number the changes no take effect, the extra dlls are not added.
So each time you uninstall the package, close visual studio and clear the Nuget Cache,
How to clear NuGet package cache using command line?
Then open again Visual Studio and reinstall the local package to make the change takes effect.
Or make the package version to increase each time to be for Visual Studio to recognize your changes.
For example:
Package-1.0.0
Package-1.0.1
Package-1.0.2
.....
To create a Nuget package from a sample project there are some ways, for example:
Right click to your Visual Studio project and choose the "Pack" option
Then install the nuget package explorer:
https://www.microsoft.com/es-ec/p/nuget-package-explorer/9wzdncrdmdm3?activetab=pivot:overviewtab
And add manually your extra references (dlls files) to your specific targets.
Create a nuget package using a .nuspec file how specified in the documentation:
https://learn.microsoft.com/en-us/nuget/guides/create-packages-for-xamarin
<files>
<file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.dll" target="lib\netstandard1.4\Plugin.LoggingLibrary.dll" />
<file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.xml" target="lib\netstandard1.4\Plugin.LoggingLibrary.xml" />
<file src="Plugin.LoggingLibrary.iOS\bin\Release\iOsDependence.dll" target="lib\Xamarin.iOS10\iOsDependence.dll" />
<file src="Plugin.LoggingLibrary.Android\bin\Release\AndroidDependence.dll" target="lib\MonoAndroid10\AndroidDependence.dll" />
</files>
In your files part add your .dll files.
And dont forget, each time you uninstall and install again the nuget package from your local source.
Or you increase the version of the package each time:
Or close Visual Studio, clean the nuget cache and Rebuild your project.
In order to take effect the changes.

Related

How can a project get its own NuGet package instead of using the one the solution uses?

I have a C# project, TrendMasterCS2, built in VS 2019 that uses a DLL, TrendData, that relies on System.Data.SQLite.Core, which I get through the NuGet Package Manager. I opened the TrendMasterCS2 sollutio and uninstalled all NuGet packages from both the executable project and the DLL project. Then, I added the System.Data.SQLite.Core package to the TrendData project. I saved all files, and then opened the project file in Notepad. I saw this:
<Reference Include="System.Data.SQLite, Version=1.0.113.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\TrendMasterCS2\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.113.3\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
This looks like a problem to me. If I ever want to use the TrendData DLL in some other solution, it's going to be carrying around this dependency on the TrendMaster2 folder. I think I can open TrendData by itself in VS2019 and add the NuGet package there, but is that what I have to do to ensure that TrendData is independent of TrendMasterCS2?
Consider to migrate from packages.config to PackageReference. (In Visual Studio, right click the packages.config and select Migrate packages.config to PackageReference...).
One benefit of PackageReference is that all packages will be restored to a global package cache directory and the tooling takes care of the actual reference path at compile time.
See https://learn.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference for details.
As an alternative you could create a nuget.config file and change the repositoryPath as described here: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file#packagerestore-section
However I did not get managed to store packages in a project-local path using nuget.config.

Nuget .symbols.package upon install doesn't contain pdb's and installs only dll's- VS 2019

I have nuget package with symbols - "Mypackage.symbols.nuget" and has dll and pdb files.
I created a local repository for testing and installed this "Mypackage.symbols.nuget" but after installing i see only dll file present in nuget folder under users directory and pdb is missing.
i tried a tweak by renaming the file manually to "Mypackage.nuget" from "Mypackage.symbols.nuget" and then i tried to install i see both dll and pdb is present after i installed.
Why does not pdb is getting downloaded when i have .symbols.nuget as i need to symbols package with dll and pdb for debugging purpose.
i created nuget package upon csproj property group.
Please suggest.
Mypackage.symbols.nuget is not a package in the form of being installed, and does not have the conditions for being installed. The purpose of this form of package is to publish to nuget.org together with nuget.nupkg. Usually, you should push the Mypackage.symbols.nupkg file into https://nuget.smbsrc.net/.
Before this, you should also push the Mypackage.nupkg into nuget.org(https://api.nuget.org/v3/index.json).
And then input the symbolsource.org(https://nuget.smbsrc.net/) into VS Symbol Server.
In this case, you could install the published Mypackage.nupkg package from the nuget.org and then it will match the related Mypackage.symbols.nupkg on the symbolsource.org so that you can debug the content of the nuget.
You can refer to this document about creating legacy symbol packages(.symbols.nupkg).
=============================================================
All of the above need to push these packages into nuget.org. And in the local, you should use that way. And Mypackage.symbols.nupkg is not an installed package for any projects.
To prove this, you can try these:
1) in my side, I add these node in csproj file to create the symbol package.
<PropertyGroup>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
Then, config the local path of it into nuget package source. After that, delete the xxx.nupkg directly,
I am sure that nuget package UI cannot find the package under the local path which proves the Mypackage.symbols.nupkg is not an installed nuget package and only be uploaded into the server.
Solution
1) just rename the Mypackage.symbols.nupkg as Mypackage.nupkg since it has the dll and pdb files.
2) use this csproj node to repack your project.
<ItemGroup>
<None Include="$(OutputPath)$(AssemblyName).pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
</ItemGroup>
And the main xxx.nupkg will contain the pdb file.
3) also use this xml node in csproj file:
<PropertyGroup>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
Note: if you want to debug the nuget package locally, you should also pack the resource files into the nupkg file.
See this thread answered by me.
In addition, using Debugging information: Embedded format might be much easier.

Nuget Dependencies not getting installed

I am running a private Nuget Server locally on IIS.
I am creating packages and uploading them all via commadline using nuget.exe (Later on I have to put this on build server, hence the command line). However there is one issue I am stuck at.
I am trying to declare dependencies. I generate the nuspec file in the folder where the .csproj file is there. Then I manually edit the nuspec file to add this under the metadata tag:
<metadata>
<dependencies>
<group targetFramework=".NETFramework4.5">
<dependency id="DemoProject" version="2.0.0.0" />
</group>
</dependencies>
</metadata>
DemoProject, version 2.0.0.0 is present on the Nuget Server.
The project I am creating package for, MyProj.csproj does not have the reference to the DemoProject added to it via Visual Studio. It is just at the packing time I want to create the dependency. It sounds strange but is needed for some initial validation.
Then I run pack command:
"C:\nuget\NuGet.exe" pack MyProj.csproj -IncludeReferencedProjects -Prop Configuration=Release
Then I push it to NuGet server using command line.
When I do an install via command line, then only MyProj package is present at the install location.
When I use Nuget Package Explorer and create a package, I can use the Package Dependency Editor to specify the dependency. It asks for the URL of my local Nuget Server and then adds the dependency. And when I install that package, it works !!
There seem to be no difference in the generated nuspec file in both the cases.
Obviously Nuget Package manager is doing something which I am missing out on.
Any hints?
More details: When I create a lib folder in the Package manager console and put my dll manually, lib->net45->MyProj.dll, then when I install the package thus created also "does not" install the dependency. Back to reading documentation again.
I know this doesn't directly answer your question but I had an issue with NuGet dependencies and my solution may possibly provide a hint.
DLL#1 was had no NuGet Dependencies. Pushed that to my private repo.
DLL#2 referenced DLL#1 NuGet package. Pushed that to my private repo.
All fine and dandy except from the Application project when I go to "Manage NuGet Packages...", the NuGet Package for DLL#2 is listed on the Browse tab but it shows no dependencies. I was forced to install both DLL#1 AND DLL#2 nuget packages. I desired to install DLL#2 nuget package and get DLL#1 automatically.
The way I fixed this was uninstalling all NuGet packages from DLL#2 solution.
Then going to Tools > Options > NuGet Package Manager > General. Then set the Default package management format to Packages.config and then unchecking the option "Allow format selection on first package install".
Then i installed all the needed NuGet packages. Now when i pack it up and push it up to the server, it shows the proper dependencies when going to "Manage NuGet Packages...".
nuget pack doesn't see the dependencies because its looking for them in the \packages folder. That folder didn't exist because I was using PackageReference for package management.
All worked after switching to Packages.config for package management.
I know the problem I had wasn't the same as yours but if you're not using Packages.config for package management, perhaps its related.
Late answer but the issue with this nuspec is <group targetFramework=".NETFramework4.5">. I feel confident that ".NETFramework4.5" is an invalid targetFramework. A full list of the available Target Frameworks is here.
When working with the Dependency section, you may not need to use the group tag. Any users who encounter similar errors would do well to read through that section. They have samples of proper usage.

NuGet package files not being copied to project content during build

I am building an MVC4 web application with VS2012 professional with NuGet Package Manager version 2.2.31210. I have multiple projects in my solution, all sharing various packages I installed using NuGet. One of my projects is an MVC4 web application where I am using packages such as bootstrap, jquery UI, etc, all installed using NuGet.
When I clone a fresh copy of my entire solution from my repository and build my MVC4 project, the package restore feature seems to be working: it creates the packages directory under the solution direcotry and populates it will all the versions of the packages I expect to see. However, the content files do not get copied to the appropriate places in the MVC app directory. The weird thing is that it does create directories for the content, but does not copy the content files themselves.
For example, I am using the Twitter Bootstrap package which appears in the packages/Twitter.Bootstrap.2.2.2. In the MVC project a directory called bootstrap (containing css, img, and js directories) gets created in the Content directory. But, no css or js files are copied into those directories!
Does anyone have a clue what magic incantation I must utter to get the build to copy these content files from the NuGet packages directory?
This is a very common issue we are all having. I've created an MSBuild Task NugetContentRestoreTask that will do this trick for you. Run the following command in the Package Manager Console:
Install Nuget Content Restore MSBuild Targets
PM> Install-Package MSBuild.NugetContentRestore
The only thing left is to call it from your BeforeBuild Target with something like this:
Project File Targets
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)" />
</Target>
You can take a look at the source repo and find it on nuget.org
Additional Content Folders
This nuget only includes the default folders scripts, images, fonts, and content, it is not a recursive directory includes. For additional content subfolders - you must assign the property AdditionalFolders.
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)"
AdditionalFolders="less;sass;common" />
</Target>
I have found a workaround, but it is ugly. By executing the following command in the NuGet Package Manager Console: Update-Package -Reinstall all the files are indeed copied to their proper places within the Mvc project Content and Scripts directories.
Unfortunately, this is risky because you are likely to end up with the wrong versions of certain packages. For example, in my case after the command finishes executing (which takes quite a while by the way), I end up with jQuery version 1.4.4. This is way old, and I assume it must be an explicit dependency of some other package that is being updated. So it appears that the order in which the packages actually get updated by NuGet is significant (it does not appear to parse the entire dependency tree for all packages and pick only the latest versions from the union of all dependencies, which seems like it would be the preferred behavior). Rather, as the command executes I see it replacing the jQuery package several times with different versions as it works its way through all the packages and their dependencies, only to end up with a very old version.
A similar approach is the execute the Update-Package -Reinstall command explicitly for each package that is causing my problem, but this is incredibly tedious and error prone.
The NuGet Package Restore feature should yield the same result as manually executing the Install-Package or Update-Package -Reinstall command for a package, but it does not.
I don't like to have the thirdparty JavaScript files under source control either. Thats why I've followed Jeff Handley advice in http://nuget.codeplex.com/workitem/2094 to create a solution my self. I didn't go the executable way, but created a nuget solution level package which does the trick.
http://www.nuget.org/packages/Baseclass.Contrib.Nuget.GitIgnoreContent/
It's tied to git, as it automatically updates the .gitignore file.
Short description:
Ignore nuget content files in git:
Generate entries in the .gitignore file to exclude nuget content files from the source repository
Restore nuget content files before building (Automatically in VS and manually with a powershell script
I've written a blog post describing how to use it.
http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0
In Visual Studio 2015 Update 1, they now support contentFiles. The caveat with this is that it only works in projects that use project.json.
In reference to the problem that you are having, there is a good blog post that explains why you see this behaviour: NuGet Package Restore Common Misconceptions.
For my projects it turned out that content files work with PackageReferences only:
Existing project with nuget references via packages.config
Installed NuGet package with content files
Build project
No content files in output directory
Conversion of packages.config to PackageReferences
Build project
Content files have been copied to output directory
IDE is Visual Studio 2017. The project is an application project which means it is in the old csproj format.

Nuget package restore with local feed

I'm trying to get nuget package restore working in a solution that is looking for packages in the regular, public nuget feed and in a local feed located on a shared network drive.
What I've tried so far is enabling nuget package restore on the solution, then editing the Nuget.targets and changing the PackageSources variable, but that doesn't seem to work. Is this possible?
My Nuget.targets file looks like this for the package sources section:
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
<!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<PackageSource Include="https://nuget.org/api/v2/" />
<PackageSource Include="\\mynetworkshare\Development\NugetPackages" />
</ItemGroup>
The error I get on build is "Unable to find version '1.0.0' of package 'MyCustomPackage'. I have verified that the nupkg exists at \\mynetworkshare\Development\NugetPackages\MyCustomPackage.1.0.0.nupkg.
The fix for me was bhuvak's answer plus I had to rename some packages.
I had been creating symbols packages (named similar to MyCustomPackage.1.0.0.symbols.nupkg) and using those from my local package feed folder. However, package restore doesn't seem to pick those up. I had to rename them, removing the .symbols portion of the file name.
After I did that, package restore works great.
Updating the sources in NuGet.targets should work.
Make sure you have added both official NuGet source and local feed explicitly in the targets file.
What error are you noticing ?
We had a similar issue to #evan. We're using the CreateNewNuGetPackageFromProjectAfterEachBuild package to create our NuGet packages on a TFS 2013 build server. We have a local, share based package source and copy the nupkg files from the build output to this share. We found that builds that reference these packages fail because NuGet package restore fails to find the packages in the local source.
Running NuGet from the command line on the build server we get strange behaviour:
nuget.exe list <search-term-for-our-packages> -allversions
always succeeds and lists each version of our packages. However, when we go to a failed build's \src folder and run
nuget.exe restore .\oursolution.sln
we always get:
Unable to find version '1.0.6.341' of package 'our.package.name'.
I tried all sorts of things to resolve this, playing with nuget.config and swapping between versions of nuget.exe but the fix was simply to do with the naming of our nupkg files. By default CreateNewNuGetPackageFromProjectAfterEachBuild names the nupkg that it generates as the package Id plus the build configuration and target. E.g.
our.package.name.1.0.6.341.Release.AnyCPU.nupkg
With this file in our package source nuget list works but nuget restore fails. When I rename the package to
our.package.name.1.0.6.341.nupkg
then nuget list and nuget restore work as expected.
Our fix is simply to modify the config file of CreateNewNuGetPackageFromProjectAfterEachBuild to prevent it including the build configuration and target. But why does nuget restore depend on the package file name whereas nuget list doesn't?