MSBuild Macro for NuGet package directory - visual-studio

I'm working on a NuGet package that adds a step to the build process by using a .targets file.
I need to reference other files from my NuGet package in order to complete the build successfully.
In the past, I've used $(SolutionDir)packages\MyPackage and all has worked fine.
However, I was just playing around with the VS 2017 RC, and I noticed that my package was installed in the global NuGet package directory, not in the solution folder.
Is there some macro that I can use from MSBuild, that contains the path for the NuGet packages folder? It is a requirement that I maintain compatibility with VS2012.

The $(NuGetPackageRoot) macro points to the package root.

You can use an alternative method that create a NuGet.Config file in the root of the \Solutions\ folder to set the package repositoryPath of VS 2017 RC, add to NuGet.Config the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
For the repositoryPath setting, you can specify an absolute path or relative path (recommended) using the $ token. The $ token is based on where the NuGet.Config is located. In this case, you package will install in $(SolutionDir)packages\ folder, you can used $(SolutionDir)packages\MyPackage for Visual Studio 2017 RC. It`s also maintain compatibility with VS2012.

Related

How to change the NuGet-package reference in a Visual Studio project to use Nuget.config

I have a Visual Studio project file with the extension .csproj. Inside it are references like this:
<Import Project="..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props"....
I have now made a NuGet.config file in the parent folder of from the solution folder. And I removed the local "packages" folder. In the new nuget.config I set up a common location for storing packages.
nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="D:\Data\NuGet" />
</config>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
</configuration>
When I building I now get this error:
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information...
The missing file is ..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props.
How can I solve this?
If I manually have to replace the (Import Project="..\packages...) elements in the project file, what should I change it to, so that it follows the configuration from the Nuget.config?
If I manually have to replace the (Import Project="..\packages...)
elements in the project file, what should I change it to, so that it
follows the configuration from the Nuget.config?
Since you use the new nuget.config file which changed the path of the local nuget reference(like this <add key="repositoryPath" value="xxxxxx" />).
And Restore will only restore the missing nuget packages but will not change to use the new nuget package location in xxx.csproj.
So you can follow my steps to resolve the issue:
Solution
1) Tools-->Nuget Package Manager-->Package Manager Console-->
type Update-Package -reinstall to reinstall these packages to reference the new right path.
2) enter the xxxx.csproj file, delete these duplicate, old import info like these:
<Import Project="..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\..\..\..\..\installed_packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" />
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
3) Then rebuild your project and will solve this issue.
Update 1
The new Nuget.config file will specify that the newly installed nuget packages use the new reference address, but for previously installed nuget packages, the reference address in the xxx.csporj file will remain the old address. The Restore procedure only restores the nuget package under the new path, but it does not make any changes to the nuget reference in xxx.csproj file, so it can only be reinstalled.
Besides, the import node is created by Microsoft.Net.Compilers props file from the build folder in the microsoft.net.compilersnuget package. And it is a nuget mechanism which can do some operation in xxx.csproj file when you install the nuget package.
However, this file is also special and when you change the nuget reference path.
Because nuget enabled the new address mechanism, during the uninstallation process, the old address of Microsoft.Net.Compilers.props is still not recognized, so it cannot be uninstalled. In fact, when you execute the reinstall nuget package, a new address has been created in the xxx.csproj file. See this:
So you should just delete duplicate files from the old address.
Visual Studio option to change the Nuget Package References
In Visual Studio Tools=> Nuget Package Manager => Package Sources.
You can change the package sources here.

Internally distribute a Visual Studio Template using Nuget and SVN

Suppose we have a Visual Studio template that we would like to distribute within our organization. This template is hosted on an SVN server. I would like users to be able to point Nuget to the SVN location and get the template installed in the proper location just like any other package. Is this possible?
Is this possible?
We can do it but individuals do NOT recommend it.
How
According to the NuGet document:
Put simply, a NuGet package is a single ZIP file with the .nupkg
extension that contains compiled code (DLLs), other files related to
that code, and a descriptive manifest that includes information like
the package's version number. Developers with code to share create
packages and publish them to a public or private host. Package
consumers obtain those packages from suitable hosts, add them to their
projects, and then call a package's functionality in their project
code. NuGet itself then handles all of the intermediate details.
However, the Visual Studio Template is a file with the .zip extension, which could not be recognized by NuGet. Even if we point NuGet to the SVN location, NuGet still can not recognize it.
To resolve this issue, we have to create a NuGet package to include this Visual Studio Template .zip file, like:
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
</files>
Besides, there is another question, when we install this nuget package to the project, this Visual Studio Template .zip file would be downloaded to the \packages folder in the solution folder. We have to move it to the Visual Studio Templates folder.
So, we have to add .targets with copy task in that nuget package to copy zip file to the Visual Studio Templates folder.
The content of .targets file:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyTemplate" BeforeTargets="Build">
<Message Text="Copy Template to template folder."></Message>
<Copy
SourceFiles="$(SolutionDir)packages\MyTemplatePackage.1.0.0\Tools\TestDemo.zip"
DestinationFolder="$(USERPROFILE)\Documents\Visual Studio 2017\Templates\ProjectTemplates"
/>
</Target>
</Project>
Finally, the .nuspec file like following:
<?xml version="1.0"?>
<package >
<metadata>
<id>MyTemplatePackage</id>
<version>1.0.0</version>
<authors>Tester</authors>
<owners>Tester</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package description</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2018</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
<file src="MyTemplatePackage.targets" target="Build\MyTemplatePackage.targets" />
</files>
</package>
Then pack this .nuspec file, add this nuget package to the SVN location, add the SVN location to the nuget package source, you can install this nuget package to the project, and build the project, Visual Studio will download that nuget package and copy .zip file to the Visual Studio Templates folder.
I have created a sample test nuget package and it work fine on my side with Visual Studio 2017, you can test it on VS2017: https://1drv.ms/u/s!Ai1sp_yvodHf2Vax7TzuC6HQUD5w
Why not recommend
Just as you can see above, it is not easy and simple to do this, we have to do a lot of things to create that nuget package. What`s more, in order to get the template we have to create a project and install that package and build the project. It pulls in too many extra operations. Besides, when you change anything in the template, you have to re-create this package and install it.
Since this template is hosted on an SVN server, you can just check it to the Visual Studio template folder, this will be more effective.
Hope this complicated answer helps.

Change NuGet package location folder

I want to change NuGet package folder, but it does not change it.
What I do is creating file nuget.config:
<configuration>
<config>
<add key="repositoryPath" value="C:\projects\" />
</config>
</configuration>
I added this file in the solution folder (in same folder where is .sln file) or in the project folder and after that restart VS, but nothing happen.
I am using Visual Studio 2017 Community.
Change NuGet package location folder
Depending on what sort of project you are using this setting may or may not be successfully to change NuGet packager folder.
If you are using a .NET Framework project that has a packages.config file then this setting will change the nuget package folder to C:\projects\.
But if you are using a project.json file, then this setting will not successful. Because project.json project doesn't support repositoryPath config.
To change the nuget packager folder, you can you can set "NUGET_PACKAGES" environment variable. Just Set "NUGET_PACKAGES" = "c:\teampackages". Or you can place a NuGet.Config file next to the solution with the following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value=".\packages" />
</config>
</configuration>
For the detail info, you can refer to this thread:
Dotnet restore does not honour nuget.config 'repositoryPath'.
Update:
I noticed that you are creating Xamarin.Forms project with Visual Studio Community 2017, the reference should be PackageReference, for this sort of project, you should use add below code to the .csproj file:
<PropertyGroup>
<RestorePackagesPath>D:\Test\packages</RestorePackagesPath>
</PropertyGroup>
Then restart Visual Studio, VS/NuGet will restore nuget packages to the D:\Test\packages, it works fine on my side, you can check my test sample:
Hope this helps.
In Tools/Nuget Package Manager/Package Manager Settings
Options

NuGet packages getting installed to the wrong folder

I'm working on a Xamarin.Forms PCL mobile app in Visual Studio 2017, using project.json for package management (I'm not using PackageReference, since Visual Studio 2017 is required for that, and some of our team are still using Visual Studio 2015). I have multiple projects within the solution, and I have multiple branches of the project, like so:
MobileApp/
packages/ <<--- (I want nuget packages to be installed here)
Branches/
DevBranchSolution/
MobileApp.sln
nuget.config
ProjectA/
ProjectB/
I want all my (projects / solutions / branches) to be able to reference packages from a single location, so you'll notice I've added the packages folder at the root level in the MobileApp folder. I have a nuget.config file per solution that looks something like:
nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="..\..\packages" />
</config>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="CustomPackagesLocation" value="..\..\packages" />
</packageSources>
<disabledPackageSources />
</configuration>
In Visual Studio when I right-click on the solution, click "Manage NuGet Packages For Solution...", and install a package (e.g. Newtonsoft.Json), I would expect that it would install those package files inside my MobileApp/packages/ folder, the location I set in the solution's nuget.config. But it doesn't. Instead the files are getting put into the global NuGet packages location, which is %USERPROFILE%\.nuget\packages.
Why? Shouldn't my nuget.config file be overriding that? I have verified that when I go to Package Manager Settings, the location of CustomPackagesLocation is correct, but apparently the repositoryPath setting doesn't seem to affect anything.
I also noticed that inside the project.json.lock and Project.nuget.targets files, the package folder is set to the global NuGet packages location (the %USERPROFILE%/.nuget/packages one). Why? Where is it pulling this value from??
Why? Where is it pulling this value from??
The default packages directory for Project.json file is %USERPROFILE%/.nuget/packages and project.json project doesn't support repositoryPath config now. This is the reason why you have changed the repositoryPath, but NuGet still put packages into the global NuGet packages location. You can refer to the same issue on GitHub.
If you want to change packages default location for project.json, you can set "NUGET_PACKAGES" environment variable. Just Set "NUGET_PACKAGES" = "....\packages". Or you can place a NuGet.Config file next to the solution with the following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value="..\..\packages" />
</config>
</configuration>
See NuGet.Config reference for details on config section.
I had a very similar problem where it wasn't using the packages folder for a class library. For some reason my csproj file had set for a few assemblies. I removed this line and did a update-package -reinstall -project myclasslibrary and it worked again just fine.
I'm not sure what set the HintPath in the first place.

Install NuGet packages to Project Dirs instead of Solution Dir?

I have a solution in Visual Studio 2015 with about 40 projects in it. Some of these projects have some NuGet packages referenced.
Due to a combination of our branching strategy (where each project folder is branched individually) and our security requirements (that the NuGet binaries are actually checked into TFS) I would like the NuGet packages for each Project to be installed into each Project's folder, not in the solution's folder. Space usage is not a concern here.
I've looked at:
https://docs.nuget.org/consume/nuget-config-file
https://docs.nuget.org/Release-Notes/NuGet-2.1#Specify-packages-Folder-Location
And they've helped my understanding of how the config files work... but I can't seem to get it to do what I want.
I've tried this in my config file:
<configuration>
<config>
<add key="repositoryPath" value="$(ProjectDir)\Nuget\" />
</config>
</configuration>
But it creates a folder in the solution folder actually called '$(ProjectDir)'.
And I can't hardcode the path to the project folders (i.e. 'C:\myteam\teampackages' in the NuGet docs) as pretty much everyone in the team have different paths to their local workspaces!
How can I do this?
Firstly, you should not check in NuGet packages into TFS Version Control. As one of the advantages of using NuGet is that you can use it to avoid checking in binaries to your version control system.
Instead, you need to restore NuGet packages during TFS build process and the required packages will be downloaded. In VS2015, you need to follow steps in this blog: https://docs.nuget.org/consume/package-restore/team-build).
Some key steps are (assume you're working with XAML build):
Add following items to the solution. (Content of the nuget.config and .tfignore file can be found here)
Add one build.proj file under the root path of the solution folder. (Content of the build.proj file can be found here)
Create one folder named tools under the root path of the solution folder. Create NuGet sub-folder under tools folder, download and save nuget.exe under tools\NuGet path.
Check in nuget.config, .tfignore, build.proj and tools\NuGet\nuget.exe into TFS version control.
Modify the build definition to choose to build the build.proj file.
Then you will have NuGet packages restored successfully during the TFS build process.
The Nuget docs mentions specifying package folder location is to have many different solutions share the same package. This is an opposite scenario as your. Repository path setting only allows you to install the NuGet packages in the specified folder (like C:\teampackages ) or for relative path (like ../Nuget).
To make installing package in different repositoryPath, you can try:
<configuration>
<config>
<add key="repositoryPath" value="../Nuget" />
</config>
</configuration>
Check case: Is it possible to change the location of packages for NuGet?

Resources