Use a .nuspec file/script to automatically install nuget packages into a new project - visual-studio

I am trying to automate the process of installing nuget packages into new visual studio projects. My idea is to reduce the time it takes to source all the packages via the nuget package manager, by specifying the packages in a custom file that can be run to install these packages. Therefore only requiring every new project to include this file and running it each time. I'm very new to nuget and have been assigned this task without much prior knowledge. I was advised that .nuspec route would lead me in the right direction, since it contains the meta data about a package. Although since consumers don't have direct access to the .nuspec file of a package, I am failing to understand how it can be used as part of this automation. I have also heard about automatic package restore, but since that only works for lost reference, I don't see how it will help in new projects that haven't necessarily referenced anything to do with that project.

note that you cannot simply drop a pre-built packages.config file into a new project and expect it to work. When installing, NuGet modifies the project file (.csproj) to include references and uses packages.config for downloading missing files (and update/conflict logic).
Using VS 2017 (released stable versions 15.2 and higher) and the PackageReference style of referencing projects, you can simply drop a Directory.Build.props file into the root of your solution containing all the projects you need:
<Project>
<ItemGroup>
<PackageReference Include="Autofac" Version="3.5.2 />
<PackageReference Include="Topshelf" Version="3.2.0 />
</ItemGroup>
</Project>
This will add these NuGet packages to all new projects in the solution without the need for the .csproj files to be modified. (note that after adding/editing this file, you need to close and re-open the solution. this should be fixed in the upcoming VS 2017 15.3 update for editing the file).

Nuget already supports automation of installation and we can use nuget commandline to achieve this
Everytime you add a nuget package in Visual Studio,it gets add to a file called packages.config file.
E.g. will look like this
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net451" />
<package id="Microsoft.Owin.Hosting" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
<package id="Owin" version="1.0" targetFramework="net451" />
<package id="Topshelf" version="3.2.0" targetFramework="net451" />
</packages>
Every project you have in your solution will have packages.config file. You can go to the parent folder of all the projects and simply run comand 'nuget restore', it will get all the packages for you.
For this to work, nuget.exe needs to be downloaded separately .More details on the nuget command line can be found here and here's the commandline reference
Edit:
Thanks #Martin Ullrich pointing out.Just to be clear, The above method will not add the references to project file automatically,it will only get the packages to the packages folder.In VS2017,the support is there which #Martin's answer addresses.
Hope this helps!

Related

Nuget Packages dependencies issue

I'm having trouble of dependencies in a chain of NuGet projects (Visual Studio 2019 and NuGet 5.7.0.6726).
The first project, include Log4Net NuGet package from NuGet.org, I package it with "nuget.exe pack mx_logging.vbproj -IncludeReferencedProjects" and I have my own (MX_Logging.nupkg).
A second Project use MX_Logging and i got the installation of Log4Net too, no problem so far...
Now, if i pack the second project too with the same method used before, it only have MX_Logging and not log4net as dependencies, how my i fix this?
This is the package.config in the second project root:
<packages>
<package id="log4net" version="2.0.8" targetFramework="net452" />
<package id="MX_logging" version="1.2.7668.29513" targetFramework="net452" />
</packages>
Thanks a lot to everyone ;-)
In my side, when I installed the second nuget project into a new net framework 4.5.2 project, it has the log4net nuget dependency.
log is the first nuget project and log1 is the second nuget project.
So please try the following steps:
1) delete bin and obj folder of the second nuget project.
2) clean nuget caches first or delete all cache files under C:\Users\xxx\.nuget\packages
3) rebuild your second nuget project and then
cd xxx\xxx\the second project folder(where exists the csproj file)
nuget spec
nuget pack xxx\xxx.csproj -IncludeReferencedProjects
4) make sure the second nuget package and the first nuget package are all under the nuget package source.
Update
I used nuget.exe cli v5.6.0 to pack the nuget project and I also test with v5.7.0. All are right.
Actually, I am guessing if you just see the second nuget package UI which does not list log4net nuget dependency.
Although it does not list log4net, but the log4net nuget dependency is under log nuget package. When you install log1 nuget package, it will install log nuget dependency with its log4net nuget dependency. And it just does not show the dependencies of the inter-generation package. But the log4net nuget package really exists. Just as my first pic shows.
But if you still want to the dependency shown on the UI, or your nuget package really has some problems, you could try this:
modify the second nuget project's nuspec file and add these:
<dependencies>
<dependency id="log4net" version="2.0.8" />
</dependencies>
The whole nuspec is like these:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>1og1</id>
<version>1.0.0</version>
<title>me</title>
..........
<tags>Tag1 Tag2</tags>
<dependencies>
<dependency id="log4net" version="2.0.8" />
</dependencies>
</metadata>
</package>
Then, repack your second nuget project.

Manage Nuget Packages Outside Visual Studio

My organization wants to segregate all the development machines on a network without internet access.
I found this article that gives that gives some nuget host product, so that the packages are available offline.
My problem is that I can't find a way to manage the package update, because the machines that have and internet access won't have Visual studio installed.
I was looking if there is a tool that reads a folder where all nupkg files are stored and check if a newer version is available and downloads it, or otherwise reads a manually created packages.config file checks for newer version and download them on a folder.
Does anyone have an idea how to manage nuget packages in this way? I spent the last week trying to find a way but I had no look.
Does anyone have an idea how to manage nuget packages in this way?
According to the NuGet CLI reference:
The update command also updates assembly references in the project
file, provided those references already exist.
So when we use NuGet.exe update the package, we are not only need the packages.config but also need the solution/project, otherwise, you will get the error:
"Unable to locate project file for 'D:\NuGetServer\packages.config'
You can copy a simple project from the machine, which have Visual Studio installed, then use below command line to update the nuget package in the package.config file:
nuget update "YourProjectPath\packages.config"
But NuGet will update the packages into the packages folder under the solution folder by default, so we need change the packages folder to the folder where all nupkg files are stored before update packages.
Detail steps:
Download the nuget.exe from nuget.org, set it to your local machines.
Create a NuGet folder under the path %appdata%, add the NuGet.Config file and change the packages folder by repositoryPath, just set it "D:\NuGetServer":
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
<config>
<add key="repositoryPath" value="D:\NuGetServer" />
</config>
</configuration>
Copy a solution from other machine, add the packages in to the package.config file:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.1.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" />
<package id="NUnit" version="3.7.0" targetFramework="net45" />
</packages>
Open a CMD file, switch to the path where NuGet is stored in step 1, then use the update command:
You will find packages in the packages.config are updated to the latest version.

how to fix ChakraCore NuGet package error?

When initializing a new React Native Windows WPF project, this error happens:
NuGet Package restore failed for project Native: Unable to find version '1.4.1-preview-00010-42060' of package 'Microsoft.ChakraCore'.
https://www.myget.org/F/chakracore-preview/api/v3/index.json: Package 'Microsoft.ChakraCore.1.4.1-preview-00010-42060' is not found on source 'https://www.myget.org/F/chakracore-preview/api/v3/index.json'.
https://api.nuget.org/v3/index.json: Package 'Microsoft.ChakraCore.1.4.1-preview-00010-42060' is not found on source 'https://api.nuget.org/v3/index.json'.
If I create a standalone project and add the same NuGet package reference, I get the same error -- even on Xamarin Studio Mac.
The problem is that the project was referencing the "preview" feed on myget.org, instead of the official release feed on nuget.org. In the NuGet.Config file(s) in your project, remove line that references the preview feed that looks like this:
<add key="ChakraCore" value="https://www.myget.org/F/chakracore-preview/api/v3/index.json" />
In the Visual Studio 2015 (or Xamarin/Visual Studio Mac) project, right-click on the project and select Manage NuGet References. From there, you can click on the Updates tab, select ChakraCore from the list, and click "Update". This should update the packages.config and other files for you. Note that if you had the project open while editing the config files you'll need to close and re-open the project to get the new settings to take hold. In some cases, the upgrade may leave behind the reference to the previous 1.4.1-preview package and you'll need to hand-edit the csproj file to get rid of it.
If you need to make this change without Visual/Xamarin Studio, you just have to edit a few text files. In the packages.config (in Visual Studio 2015), change the line referencing the 1.4.1-preview version to the latest release (1.5.2 as of this writing):
<package id="Microsoft.ChakraCore" version="1.4.1-preview-00010-42060" targetFramework="net46" developmentDependency="true" />
becomes
<package id="Microsoft.ChakraCore" version="1.5.2" targetFramework="net46" developmentDependency="true" />
In your project's csproj file:
<Import Project="$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props')" />
becomes
<Import Project="$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props')" />
and
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props'))" />
becomes
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props'))" />
Generally speaking, don't reference preview packages from myget.org in production projects or project templates others will use. They can be removed at any time, and security updates may not be published there with the same regularity as official channels.
Looks like the preview Microsoft.ChakraCore NuGet package was removed from the MyGet feed.
The main NuGet.org site only has stable releases for the Microsoft.ChakraCore NuGet package.
So you are left with editing any references to the package and using a published version. Microsoft.ChakraCore version 1.4.4 should work.
There is also an open issue about this on the React native GitHub site.

Nuget Restore Doesn't work at all

A Project with NuGet packages won't compile, the error is: "The project references NuGet package(s) that are missing on this computer, Enable NuGet Package Restore to download them."
Here's the Nuget Restore Option in Visual Studio:
If I look at the reference in the project, I see more than just the Nuget Packages missing!
If I attempt a restore at Solution layer...
If I attempt the Package Manager Console option of:
update-package -reinstall -projectname myProjectName
The output window successfully uninstalls and then reinstalls all the packages!
None of the references are good they are still all Yellow-Flagged as in the image above.
The Packages.Config File looks like this:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.4.0" targetFramework="net45" />
<package id="Selenium.Support" version="2.53.1" targetFramework="net45" />
<package id="Selenium.WebDriver" version="2.53.1" targetFramework="net45" />
<package id="Selenium.WebDriver.ChromeDriver" version="2.23.0.1" targetFramework="net45" />
</packages>
When did this start failing?
Today I had to create a solution that included all the projects in a folder (with just one of them being the one shown in example above). I named it the AllSolutions.sln. When I added all of those projects, I got Nuget errors saying pacakges were missing. I attempted, with success, restoring all NUGET pkgs. using the solution level "Restore all Packages". The compile then worked for AllSolutions.sln.
I then opened a single one of the solutions from my C:drive (mapped to TFS properly). This is when the problem shown above surfaced.
Compile is working now, here was the solution:
I restarted Visual Studio, connected to TFS and clicked on the same solution as before. But this time, the project had new items in it as follows:
The .nuget folder was the original folder which apparently disappeared when I included this project in the AllSolutions.sln. (Note I did not manually delete this folder). The second is an internal project we have that just specifies what packages we use in the packages.config file.
I have no idea why reconnecting to TFS, opening the Solution file from the Team Explorer menu, (after a VS reboot) fixed this issue. But maybe this will help someone else.
And as proof, the original "Yellow Tagged" references shown above now look like this:
Root Cause:
I believe that including the same project in multiple projects has side effects related to Nuget restrore. The reason is that the .nuget folder is removed as shown in this post.
What was learned:
Migration of Nuget scripts was not necessary.
If your project is having this problem it can be related to a missing .nuget folder! Good luck in getting it restored.

Should NuGet.VisualStudio.Interop.dll be in the GAC to use it as a wizard?

I am creating a project template. I would like to have it auto install unity and prism via NuGet.
I read here how to do that. I setup my vstemplate file like that page indicates:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardData>
<packages>
<package id="CommonServiceLocator" version="1.0" />
<package id="Prism" version="4.1.0.0" />
<package id="Prism.UnityExtensions" version="4.1.0.0" />
<package id="Unity" version="2.1.505.0" />
</packages>
</WizardData>
It seems to be setup right, but it does not work. When I try to use my template I get this error message:
Could not add all required packages to the project. The following packages failed to install from 'C:\Users\MyUser\AppData\Roaming\Microsoft\VisualStudio\10.0\ProjectTemplatesCache\MyTemplate.zip'
I did some looking, and for a Wizard to work, it needs to be installed in the GAC. I ran this command:
gacutil.exe /l NuGet.VisualStudio.Interop
And it returned:
The Global Assembly Cache contains the following assemblies:
Number of items = 0
So it seems it is not in the GAC. The question is: How does this work for everyone else then? If it needs to be in the GAC, then why is it not there automatically?
If not, then why does it not work (I am fairly sure it needs to be in the GAC though).
Note: I did find that dll here:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft Corporation\NuGet Package Manager\1.6.21215.9133
I found that I had missed this important part of the docs:
The template needs to specify where to find the package nupkg files. Currently two package repositories are supported:
Packages embedded inside of a VSIX package.
Packages embedded inside of the project/item template itself.
So, there is no way to get packages from the actual NuGet Repository.
Answer for this Question:
Open Visual Studio > Tools > Extensions and Updates > choose Online link and then right side search bar type NuGet Package Manager. Then Download and Install. Solves your problem

Resources