Bhavya

Code -> Break -> Fix -> Blog

VS Templates : User to select NuGet packeges to be pre-installed for Project Template

2 Comments

In my previous blog, I talked about creating a project template, how to pre-install NuGet packages to it and how to use VSIX to deploy the template.

Say, I want to give an option to the end-user to select the NuGet package(s) he/she wants to install from the list of packages availed to her. Lets try to achieve this in this blog.

1. Create a list of all the NuGet packages that you want to provide to the user. And download all the required .nupkg files too. I want to give the below list to the user for selection (This list is just to explain the topic here they may or may not be related).

EntityFramework v6.1.3  (http://nuget.org/api/v2/package/EntityFramework/6.1.3)

Newtonsoft.Json v6.0.8 (http://nuget.org/api/v2/package/Newtonsoft.json/6.0.8)

Microsoft.Net.Http v2.2.29 (http://nuget.org/api/v2/package/Microsoft.Net.Http/2.2.29)

2. Add all the 3 .nupkg files to the template project and also to .vstemplate so that they are part of the template that will be shipped.

3NuGetPackagesInTemplateProject

3. Create a wizard that will ask for NuGet package selection. For that we will need to show a dialog to the user to select the items. To do some processing when the template is getting created we need to implement the IWizard interface.

Using the IWizard interface we need to show the NuGet package selection Dialog. Let’s try to achieve this in the following steps.

4. Add a new Console Application project to the solution we created in the previous blog.

TemplateWizardProject

5. Create a class under Console Application which will implement IWizard. Add EnvDTE and Microsoft.VisualStudio.TemplateWizardInterface references to get the reference of IWizard and ProjectItem type. Also add a WindowsForm to the same project (required references System.Windows.Form and System.Drawing). I have created ProjectOneWizard.cs class and SelectNugetForm.cs windows form. Form is required to popup a dialog which will have the list of NuGets.

WindowsFormInProject

6. IWizard interface has the list of methods that needs to be implemented.

public void RunStarted(object, Dictionary<string, string>, WizardRunKind, object[]) -> Called at the beginning of the template wizard run. The Dictionary holds the standard parameters to be replaced. The last parameter can hold the custom Parameter list.

public void RunFinished() -> Called when the wizard has completed all tasks.

public void BeforeOpeningFile(ProjectItem) -> Called before opening an item in the template. This is related when OpenInEditor is set to true for an item in .vstemplate.

public void ProjectFinishedGenerating(Project) -> Called when a project has finished generating.

public bool ShouldAddProjectItem(string) -> Indicates whether the specified project item should be added to the project.

public void ProjectItemFinishedGenerating(ProjectItem) -> Called when a project item has finished generating. Not relevant for Project Template.

So we will show the Nuget selection Dialog box under RunStarted(…). Here I am showing SelectNugetForm, in this form write the logic which gets the list of Nuget packages to be installed. And under ProjectFinishedGenerting(project) install the packages.

For me I am returning the list of packages as string with semi-colon (;) and the ID & version of the package separated using colon(:) like my return string might be like “Microsoft.Net.Http:2.2.29;Newtonsoft.Json:6.0.8;EntityFramework:6.1.3”. And when I am reading the string I can pull the packageID and it’s version via : and fetching different nugets via ;.

public void RunStarted(object automationObject, 
Dictionary<string, string> replacementsDictionary, 
WizardRunKind runKind, 
object[] customParams)
{
var selectNugetForm = new SelectNugetForm();
var result = selectNugetForm.ShowDialog();

nugets = result == DialogResult.OK ? 
selectNugetForm.SelectedNuGets : string.Empty;

selectNugetForm.Close();
}

public void ProjectFinishedGenerating(Project project)
 {
 if (string.IsNullOrEmpty(nugets))
 {
 return;
 }

var componentModel = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel;
 if (componentModel == null)
 {
 return;
 }

var installer = componentModel.GetService<IVsPackageInstaller>();
 var nuGetList = this.nugets.Split(new char[] { ';' }).Select(nuGet => nuGet.Split(new char[] { ':' }));
 foreach (var nuGetDetails in nuGetList)
 {
 installer.InstallPackage("http://packages.nuget.org", project, nuGetDetails[0], nuGetDetails[1], false);
 }
 }

7. Add the wizard extension to .vstemplate file of template project so that when the template is selected by the end-user the wizard that is created in the previous step will get executed.


 <WizardExtension>
 <Assembly>ProjectOneTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97d9e18aa34ef2e5</Assembly>
 <FullClassName>ProjectOneTemplateWizard.ProjectOneWizard</FullClassName>
 </WizardExtension>

8. Also need to add the Wizard assembly to the VSIX manifest as an asset so that the assembly is shipped correctly.

WizardProjectToVSIX

Thats it!!! Now build the VSIX project & install the extension and try out the new template. To help doing this check out my previous blog.

Let me know your thoughts.

~BS

Twitter Logo

Advertisements

2 thoughts on “VS Templates : User to select NuGet packeges to be pre-installed for Project Template

  1. Can you share the code files for this blog?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s