How to add nuget packages and run custom project wizard? - visual-studio

I built my own project template. When a project is created with the template, a custom wizard is launched that allows the user to edit the project that was created.
The problem is that I also need to add some very simple nuget packages to the created project (just mvvmlight, MyToolkit and 1 other). To do this I added a WizardData element to my vstemplate with the right packages.
Here comes the problem: in order to launch my custom wizard, I need to put a reference to my wizard inside the WizardExtension element. But in order to install the nuget packages automatically I need to place a reference towards NuGet.VisualStudio.TemplateWizard inside my WizardExtension element, and the WizardExtension can only have one class that it will instantiate, but I have 2 that need to run.
So how do I solve this?
Here's the code that launches my own wizard. Now I just need the NuGet packages to install too:
<WizardExtension>
<Assembly>PartyTemplateWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=7eb2f41084fd4cd5</Assembly>
<FullClassName>PartyTemplateWizard.Wizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="template">
<package id="MvvmLight" version="4.1.27.0" />
<package id="MvvmLightLibs" version="4.1.27.0" />
<package id="MyToolkit" version="1.14.0" />
<package id="linqtotwitter" version="2.1.06" />
</packages>
</WizardData>
Does anyone have a solution?

Well, I came across the same issue and was disappointed to find no answer for this post. Now I've got the answer and I'm posting it.
There cannot be two wizard extensions. So you need to instantiate NuGet from your custom wizard (see below) and delegate all methods to this instance.
Add these lines to the RunStarted method:
Assembly asm = Assembly.Load("NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a");
wizard = (IWizard)asm.CreateInstance("NuGet.VisualStudio.TemplateWizard");
And, call the method on the instance like this:
wizard.RunStarted(automationObject, replacementsDictionary, runKind, customParams);
Similar way delegate to the wizard instance in all methods.

Instead of trying to place multiple references in one WizardExtension element - you can add multiple WizardExtension elements (one for each assembly reference).
For example:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardExtension>
<Assembly>PartyTemplateWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=7eb2f41084fd4cd5</Assembly>
<FullClassName>PartyTemplateWizard.Wizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="extension" repositoryId="your-extension-id-here">
<package id="MvvmLight" version="4.1.27.0" />
<package id="MvvmLightLibs" version="4.1.27.0" />
<package id="MyToolkit" version="1.14.0" />
<package id="linqtotwitter" version="2.1.06" />
</packages>
</WizardData>
References used:
Xamarin Forms Templates (you can refer this vstemplate file in the repository)
Packages in Visual Studio templates
How to specify two wizard assemblies under tag in project template to create mvc4 application (vs2010)
Disclaimer: I have tested this on Visual-Studio-2015 only; not on Visual-Studio-2012 (although a quick look through the answers on this link seems to indicate that it is supported on VS2012 too)

Related

ReactiveUI - The type 'IScheduler' is defined in an assembly that is not referenced

I'm trying to subclass ReactiveList so it responds to changes in a ReactiveDictionary I have written, rather than a parent List.
This is the class and constructor signature for the ReactiveList subclass.
public class ReactiveDictionaryDerivedList<TKey, TValue, TDerived> : ReactiveList<TDerived>, IReactiveDerivedList<TDerived>
{
public ReactiveDictionaryDerivedList(
IReadOnlyReactiveDictionary<TKey, TValue> dict,
Func<TValue, TDerived> selector,
Func<TValue, TDerived, bool> derivedValueFinder,
IScheduler scheduler)
{
}
Here are the dependencies I have in the project. Notice that I'm using the 4.0.0 preview release of System.Reactive, since this is installed by the ReactiveUI 8.0.0 alpha. (I'm using the ReactiveUI alpha as this seems to be what is recommended these days)
<packages>
<package id="ReactiveUI" version="8.0.0-alpha0113" targetFramework="net452" />
<package id="ReactiveUI.WPF" version="8.0.0-alpha0113" targetFramework="net452" />
<package id="Splat" version="2.0.0" targetFramework="net452" />
<package id="System.Reactive" version="4.0.0-preview00001" targetFramework="net452" />
</packages>
The problem is that the class doesn't compile because of the error:
error CS0012: The type 'IScheduler' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Reactive.Interfaces, Version=3.0.1000.0,
Culture=neutral, PublicKeyToken=94bc3704cddfc263'.
Any ideas how to resolve would be appreciated. Advice on the recommended versions for ReactiveUI and System.Reactive would also be nice.
In my WPF app I had to install the System.Reactive.XXXXX packages with version 4.0.0-preview00001 (Core, Interfaces, Linq, PlatformServices, Windows.Threading, Windows.Forms).
All these packages come with the System.Reactive.Compatibility package (nuget link):
Reactive Extensions (Rx) Compatibility Library for enabling v3 apps to
work with v4
You should try using it in your project.
Unfortunately something fishy is going on with dependencies at the moment. But for the current 8.0 version it's recommended to install System.Reactive 3.1. That's the only version 8.0 is tested against.
If you start using PackageReference for your projects, you won't need to define the System.Reactive dependency yourself, but it's picked up by the package manager. But that might not work (yet?) with WPF.
See: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files

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.

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

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!

How are packages.config paths resolved?

I have a project with a packages.config file. I do have a corresponding library. When I attempt to build my solution in Visual Studio, it does find the library, and everything works. But Xamarin Studio on my mac fails to find the same library.
For me, part of the problem is that I don't understand how the contents of the "packages" file corresponds to the path. It's clearly not a direct correspondence.
Here is the packages.config file. The relevant package is "splat".
EDIT: the answer was apparently that I needed to restart my computer. That said, it would still be interesting to know how it chooses the path.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="portable-net45+wp80+win+MonoAndroid10+MonoTouch10" />
<package id="Splat" version="1.2.1" targetFramework="portable-net45+win+MonoAndroid10+MonoTouch10" />
</packages>
And here is my packages directory in the finder:
WJ-macbook:packages william$ ls -RF
./Splat.1.2.1:
Splat.1.2.1.nupkg lib/
./Splat.1.2.1/lib:
MonoMac/ monoandroid/
Net45/ monotouch/
NetCore45/ wp8/
Portable-Net45+WinRT45+WP8/
./Splat.1.2.1/lib/MonoMac:
Splat.dll Splat.dll.mdb
./Splat.1.2.1/lib/Net45:
Splat.dll Splat.pdb
./Splat.1.2.1/lib/NetCore45:
Splat.dll Splat.pdb Splat.pri
./Splat.1.2.1/lib/Portable-Net45+WinRT45+WP8:
Splat.dll Splat.dll.mdb
./Splat.1.2.1/lib/monoandroid:
Splat.dll Splat.dll.mdb
./Splat.1.2.1/lib/monotouch:
Splat.dll Splat.dll.mdb
./Splat.1.2.1/lib/wp8:
Splat.dll Splat.pdb
On Windows the NuGet installation process will actually modify the relevant project file to include a hint path for the packages. Here is a line taken directly from one of my projects
<Reference Include="EditorUtils, Version=1.3.0.0, Culture=neutral, PublicKeyToken=3d1514c4742e0252, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\EditorUtils.1.3.0.0\lib\net40\EditorUtils.dll</HintPath>
</Reference>
The HintPath here is the method by which MsBuild discovers the EditorUtils reference. This was added by NuGet during installation.
I do not know what the equivalent mechanism is on xamarin unfortunately although I imagine it's quite similar

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