NuGet package files not being copied to project content during build - nuget

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.

Related

How can I deploy a PS1 script with a nuget package

I have a PS1 script that I use in all my projects to sign the assemblies. Until now I copied this file over to all my projects. Now I wanted to create a nuget package with the PS1 file.
I created a nuspec file and put the file in "content". Unfortunately nothing happened. Then I tried to put it in lib. Still noting happened. When I restore the package in my project no files where created in this project.
When I analyst the nupkg file with my 7-Zip the file looks OK. The ps1 file was in content, lib respectively.
I didn't found anything to this topic online. Can someone explain to me, how to create such a NuGet-Package?
When a project using packages.config installs a NuGet package, the package's tools\install.ps1 script will run. However, this no longer happens when the project using the package uses PackageReference (such as SDK style projects, used by .NET Core).
Similarly, the files in the content folder of the nupkg are copied into the project on install, but only when the project uses packages.config. PackageReference projects use the contentFiles folder in the nupkg, however the behaviour is different. Those files are copied only on build, not install, for .NET Framework projects and on publish for .NET Core projects. Probably not what you want for signing assemblies.
The feature you probably want to use is including MSBuild props and targets in your package. Note that the props and targets file names must match the package id exactly for NuGet to use them. You probably want to use afterTargets="build" at a guess.

Create a NuGet package with only javascript files

I want to create a NuGet package that contains only javascript. I have no assembly that needs to be built and included.
So to do this I created an empty solution in vs, and created an empty project. In the project I created a Scripts directory with my javascript files. I have a package.nuspec and a packages.config
When I run "nuget pack" commandline I get an error:
C:\MyProject>nuget
pack
Attempting to build package from 'TestProject.csproj'.
MSBuild auto-detection: using msbuild version '16.1.76.45076' from
'C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\MSBuild\Current\bin'.
Error NU5012: Unable to find 'C:\MyProject\TestProject.exe'. Make sure the project has been built.
C:\MyProject>
If I try to build the project in visual studio, I get an error...
Program does not contain a static 'Main' method suitable for an entry
point.
...which makes sense because I made this from an empty project.
I am not trying to deploy the assembly, just javascript, can I stop it from trying to build somehow?
Don't use a project. Have have your .nuspec and javascript files in the directory, then run nuget pack. If the nuspec doesn't contain a <files> section, then it will just copy the filesystem structure directly into the nupkg.
Having said that, new ASP.NET Core projects from Microsoft's templates no longer use front end resources (html, javascript, css) from NuGet packages, but rather use either LibMan or npm, to be more in-line with what the non-.NET front-end ecosystem uses. I suggest investigating those technologies and using them if possible.

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.

Nuget package restore is not working on TFS build server

I followed this blog post and I expected Nuget to just work. It obviously has not. I get errors on all of my third party dll's that I expect NuGet to update automatically:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\
Microsoft.WebApplication.targets (182): Could not copy the file "bin\AutoMapper.dll"
because it was not found.
I have set everything up correctly and I have ensured that the solution has Package restore enabled. If I delete a package locally and build, NuGet restores that package for me.
I am not sure why it is not fuctioning on the build server though.
Any Suggestions?
Try to add NugetRestore Activity to the TFS workfolw
Note:
For Team Foundation Build 2013 on-premises and Visual Studio Team Services (formerly Team Foundation Service), the default Build Process Templates already implement the NuGet Package Restore workflow without any special configuration.
I came across a similar error for log4net nuget package and I solved it in a different way. May be this will be useful to someone some day.
The error from TFS Team Build 2015
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications\
Microsoft.WebApplication.targets (182): Could not copy the file "bin\Log4net.dll"
because it was not found.
Cause
The path to the nuget package in the .csproj file for referencing the package in the project cannot be found
Resolution
Edit the .csproj file of the project that has the error.
Look for the node ItemGroupin the .csproj file
You will see the HintPath pointing to a folder, most like the folder contain the name of solution as where it will file the DLL.
Replace the HintPath with <HintPath>..\..\Assemblies\3rd party\log4net\1.2.10.0\2.0\log4net.dll</HintPath>
You nuget package library may not be log4net but a different library. A very easy way would be to be edit the .csproj file of a project in the solution that contains the same nuget package library, copy the reference of the nuget in the ItemGroup and replace in the project that has the error. The reference should start contain ...\Assemblies\3rd party\ ... instead of a physical file location on your machine

Create nuget package with multiple DLLs

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.