Why windows C# projects contain nuget executable in .nuget folder? - nuget

I don't understood the overall scheme on how NuGet is used on windows platform (because I never saw this, I work with Linux and monodevelop).
In many windows projects, there is a .nuget folder in repository, like
https://github.com/YAFNET/YAFNET/tree/master/yafsrc/.nuget
In this folder there is a nuget.exe executable.
Why it is necessary to add executables to source code control(SCC)?
How NuGet build tool differs from all other binary tools like compilers, which are not included into SCC?
Why other package managers like paludis are not added to SCC, but nuget does?
What are exactly the reasons to put NuGet to SCC?

It is not necessary to add NuGet.exe to source control.
The reason some projects have .nuget/NuGet.exe, with a set of other MSBuild files, is to use the MSBuild based package restore. The MSBuild based package restore will run NuGet.exe at build time to download any missing packages.
The MSBuild based package restore has been deprecated by the NuGet team.
Visual Studio with recent versions of the NuGet Package Manager will automatically restore NuGet packages before building the project. If you need to restore NuGet packages on a build server you can use NuGet.exe to restore the NuGet packages by running a command line similar to:
NuGet.exe restore YourSolution.sln

Related

Force NuGet pack to use short folder names for PCL projects

I'm having a problem with NuGet producing different output folders when run locally to the version on my build server.
When I build my PCL project locally (using nuget 2.8.6), the folder structure within the nuget package is:
lib
- portable-net45 win wpa81 wp80 MonoAndroid10 xamarinios10 MonoTouch10
- HC.Common.dll
However when I build it on our build server (TeamCity, nuget 2.8.2) I get the following folders:
lib
- portable-Profile259
- HC.Common.dll
How can I ensure that both builds output consistent folder structures? It makes switching between the "published" version and my test versions quite tricky as the reference paths do not match between versions.
Is there a way to force nuget to use the short "Profile259" name?
NuGet will normally replace the PCL profile with the individual target frameworks if it can determine them.
On your build server it looks like you do not have the the PCL profile xml files installed so NuGet is not converting the directory. So I am assuming you are using NuGet pack YourProject.csproj. If you used NuGet pack YourNuGet.nuspec the directories in the .nupkg would be the same on both machines.
I do not know of any NuGet package that uses a PCL directory of the form portable-Profile78 and I am surprised this works but it seems to. All NuGet packages with PCLs have directories of the form:
portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10
So to make them consistent on both machines you will need to either install the PCL profiles on the build server or use NuGet pack YourNuSpec.nuspec so that the directories are not renamed by NuGet.exe.

OctoPack failing in TFS Build

I'm using Visual Studio Online with Visual Studio 2013. The build fails with
You are trying to build with OctoPack, but the NuGet targets file that OctoPack depends on is not available on this computer. This is probably because the OctoPack package has not been committed to source control, or NuGet Package Restore is not enabled
According to this link https://octopusdeploy.com/blog/octopack-3.0 I need to make some changes to get package restore working properly, but another link within the previous one says that no configuration is required if using VS2013 and Visual Studio Online Nuget.org
When I build in VS all of the packages get restored first and then the project builds. Also if I build the project and invoke Octopack via command line everything works fine. Thoughts?
If you do run NuGet Package Restore before building, this should work. However, make sure the path in your project file referring to OctoPack.targets is correct - you might have moved your packages folder or the project file and the relative paths no longer match. Easiest way to fix it would be to run Update-Package -Reinstall Octopack.
NuGet Package Restore was recently changed so you wouldn't need to include NuGet in the solution to do a package restore. However, OctoPack still needs NuGet on the path so it can find it. You can try explicitly specifying the path to NuGet by adding this parameter when calling OctoPack.
/p:OctoPackNuGetExePath=<path>\nuget.exe
You just need to check in the Octopack targets file.
\packages\OctoPack.2.0.26\targets\OctoPack.targets

how to get all nuget dependencies for offline installation

I two computers, one with internet connection and the other one without.
I want to install a Nuget package (Nuget.server) with all its dependencies on the offline computer.
Unfortunately it is not possible just to download the package itself and I have to download all dependencies manually and there are dozens of them.
How can I create a package on the computer with internet connection that contains all dependencies?
Thanks.
I just went through the pain of this and wanted to find a solution using only the NuGet CLI. Turns out it's pretty simple really:
> nuget.exe install <PACKAGENAME> -OutputDirectory <OUTPUTDIR>
The key is the -OutputDirectory switch which makes the CLI install the specified package into a directory that doesn't have a project file in it. Running this command will download the package and all of its dependencies into the output directory, with each package put into a separate sub-folder. You can then grab all of the .nupkg from the output directory and do whatever you need to do with them.
Update: As Igand points out in the comments, the -OutputDirectory switch is not actually required. If omitted nuget.exe will just download into the current folder. Still best to not download it into a folder with a project file in it (unless that is what you're after).
I had a similar need, so I created NuSave.
Cache a single NuGet package with dependencies
nusave cache package "Newtonsoft.Json#12.0.3" --targetFrameworks ".NETStandard#1.0,.NETStandard#1.3" --cacheDir "C:\path\to\my-local-feed"
Cache multiple NuGet packages from a .csproj file
nusave cache csproj "C:\path\to\project.csproj" --cacheDir "C:\path\to\my-local-feed"
Cache multiple NuGet packages from an .sln file
nusave cache sln "C:\path\to\solution.sln" --cacheDir "C:\path\to\my-local-feed"
Restore & build a solution offline using my local cache
cd C:\path\to\my-solution
dotnet restore --packages C:\path\to\my-local-feed
dotnet build --no-restore
On the computer with internet access the NuGet packages (.nupkg) should be in the local machine cache. On Windows this is in the directory similar to:
C:\Users\YourUsername\.nuget\packages
So you should be able to copy the .nupkg files from there to the computer without internet access. I would create a directory on that computer and setup a new package source pointing to that directory. Alternatively you could copy the .nupkg files to the local machine cache, just be aware there is a limit of 200 NuGet packages in the cache. Then you can create a package source pointing to the cache.
Use the dotnet restore command with the --packages flag, which will download the packages to a specified directory.
dotnet restore --packages <TargetDirectory> <ProjectPath>
Ref: dotnet restore
Specifies the directory for restored packages.
A little late to the discussion here but I just ran into the same issue. I work with a medium size software development shop that works offline. Many new NuGet packages have very large dependency trees. Trying to walk the tree manually and download all required packages was very cumbersome. In the end, I wrote the NuGet Dependency Downloader. With it you give a package ID, optionally a version, and choose if you want to allow pre-release packages. After you click "Start" it will pull down the listed package and any dependencies it needs to run. As an example, when I put in "Microsoft.AspNet.Mvc" and selected "pre-release", this tool brought down 158 packages for MVC 6.0 RC1. Hopefully this will help those working in an offline environment.
https://github.com/StuffOfInterest/NuGetDependencyDownloader
In your csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<PropertyGroup>
Or dotnet publish with all assemblies references.

Download Nuget Packages Without VS/NuGet Package Manager

How can I download NuGet Packages outside of visual studio? so it can be used to create offline packages.
How to download NuGet Package without Visual Studio or Nuget Package Manager:
Search your desired package at NuGet Official Site.
Copy the end of the URL of the package page.
For Example: http://nuget.org/packages/EntityFramework => Package Name is "EntityFramework"
Enter the URL: http://packages.nuget.org/api/v1/package/{Package Name}
For Example: http://packages.nuget.org/api/v1/package/EntityFramework
You can download NuGet packages outside of Visual Studio using:
NuGet Package Explorer
NuGet Package Explorer is a ClickOnce application which allows
creating and exploring NuGet packages easily. After installing it, you
can double click on a .nupkg file to view the package content. You can
also load packages directly from the official NuGet feed.
Open a package from online feed:
And export the package to the desired location:
Install the NuGet command line program:
The NuGet command line may be installed onto a machine in a few possible ways.
Direct download of the executable from https://dist.nuget.org/win-x86-commandline/latest/nuget.exe. The executable may be placed anywhere on the file system, and in most cases should be placed in a directory that is listed in the PATH environment variable.
Install the NuGet.CommandLine package from the NuGet Visual Studio client and either move nuget.exe to a common location or execute it in the context of your project.
Install the NuGet.CommandLine Chocolatey package using the Chocolatey client. More information on Chocolatey can be found at [http://chocolatey.org].
Then run nuget install package to download and install package in the current directory.
More about the NuGet command line program:
Command Line Reference
Chrome Plugin "NuTake" provides a direct download link.
Rename extension to .zip and extract
You can download nuget packages using - vnuget.org.
On this website you can also view content of nuget package - http://vnuget.org/packages/Microsoft.AspNet.Mvc/5.2.3.
Here are a few examples that can add to DeePak's answer:
This one downloads AutoMapper from NuGet.org
nuget.exe install AutoMapper -OutputDirectory c:\Temp\LotsOfPackages -Version 6.2.2
This one downloads MyCustomPackage from an internal TFS Nuget feed
nuget.exe install MyCustomPackage -OutputDirectory c:\Temp\LotsOfPackages -Source "http://tfs.myCompany.com:8080/tfs/TFSArea/_packaging/FeedName/nuget/v3/index.json" -Version 1.0.0.2
Notes
Keep in mind that the install command will get the package in question AND all its NuGet dependencies. So, be careful about just dumping this into the directory where you running. Thus, I added OutputDirectory to the command.
For internal Nuget packages/feeds, the Source URL is available via TFS. Go to your packages tab and find your specific feed URL. If it has any spaces that have been encoded with %20, you need to replace them with spaces.
CLI command reference
Copy packages from one NuGet feed to another

Using nuget to update project files outside of Package Manager Console

Nuget.exe only supports managing packages at a file system/configuration level. The powershell commands command the magic that update the .proj files.
With that said, i need the ability to update a csproj file with the latest version of a NuGet package outside of visual studio (automated).
Basically, how do I use Install-Package (or any of the other methods) inside of an external powershell script of my own?
UPDATE:
I would like to ability to add project references outside of VS for the following reason.
My company has a lot of shared libraries that depend on each other in some cases. I am using TFS Nugetter to build and publish nuget packages from TFS. I want to ensure that the developers can't queue a build (package) unless the project can build and run on all the newer versions. This ensures that all the newer versions of the libraries work with all the newer versions of its dependencies. If the build fails, then you need to update your nuget reference in VS and fix the compiler errors/unit tests.
I have been looking at the NuGet source and I think I found an easy way to reuse NuGet source to modify proj files outside of VS (kinda).
System.Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.10.0", true);
var dte = (DTE)System.Activator.CreateInstance(t, true);
dte.Solution.Open(
#"C:\Users\paul.knopf\Documents\Visual Studio 2010\Projects\SLNMemory\SLNMemory.sln");
Basically, open an in-memory version of visual studio, run the nuget commands, then save.
In a build step, after GetWorkspace, I would like to run this in-memory vs to update all nuget references to the latest version.
What do you think? It would definitely be slow, but we would be on the same code base and have all the functionality we need.
Automating Visual Studio as you describe is certainly a possibility.
Another way I looked at was using SharpDevelop to install NuGet packages outside of Visual Studio. The NuGet PowerShell cmdlets were modified to accept a solution and you could automate installation, including the use of PowerShell scripts in a NuGet package, from the command line. The code has not been updated so it targets an old version of NuGet but could be updated. Again this is similar to your solution and fairly heavyweight solution.