Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VSIX with Project Templates and NuGet Packages

I have been following this post about how to build a VSIX project that will add some custom MVC project types:

http://www.asp.net/mvc/tutorials/mvc-4/custom-mvc-templates

I also want to include some additional Nuget packages, so I was following this page from Nuget, but it seems to be for VS2010 and I'm working in 2012.

I have the project building, and everything works peachy on my machine. The install works, the new project type appears, and when I create a new project of this type, everything works perfectly.

However, when I send the installer to a coworker, things break. The installer works, they see the new project type, but when creating the project he gets error messages about not being able to install any of the packages in the extension node. I've confirmed the Product Id of the extension is correct (I intentionally malformed it in the .vstemplate file during testing and it gave an entirely different error). I've added the packages to the extension manifest, but it doesn't seem to make a difference. I've also confirmed the .nupkg files get deployed to %ProgramFiles(x86)%\Microsoft Visual Studio 11.0\Common7\IDE\Extensions.

Any suggestions on what to do?

Custom Project's .vstemplate section

<WizardExtension>
    <Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardData>
    <packages repository="registry" keyName="AspNetMvc4VS11" isPreunzipped="true">
        <package id="EntityFramework" version="5.0.0" skipAssemblyReferences="true" />
        <package id="jQuery" version="1.8.2" />
        <!-- snip -->
    </packages>
    <packages repository="extension" repositoryId="SampleExtensionId">
      <package id="Unity" version="3.0.1304.0" targetFramework="net45" />
      <package id="Unity.WebAPI" version="0.10" targetFramework="net45" />
      <!-- snip -->
    </packages>
</WizardData>

source.extension.vsixmanifest Asset tags

<Assets>
    <Asset d:VsixSubPath="ProjectTemplates\CustomMVCTemplate" etc/>
    <Asset Type="Unity.3.0.1304.0" Path="Packages\Unity.3.0.1304.0.nupkg" />
    <Asset Type="Unity.WebAPI.0.10" Path="Packages\Unity.WebAPI.0.10.nupkg" />
    <!-- snip -->
</Assets>

File Structure

  • Extension Project
    • Packages
      • NugetPackage 1
      • NugetPackage 2
      • etc
    • ProjectTemplates
      • CustomMVCTemplate
        • <custom project files>
    • source.extension.vsixmanifest
like image 997
greven Avatar asked Jul 12 '13 17:07

greven


People also ask

How do I import a project template into Visual Studio?

Project -> Export Template… Select Project Template. Select source Project. In the Template Options I choose to Automatically Import the template to Visual Studio.


2 Answers

I've made a step by step video on how to make a VSIX that auto downloads nuget packages.

http://www.youtube.com/watch?v=_ZvsFz41H-E

Since there are many steps and I never wrote them down, I won't type them here. I've definitely tested my VSIX package on other people's machine and it worked so hopefully this will work for you.

like image 92
Min Avatar answered Sep 20 '22 15:09

Min


To download latest versions of NuGet packages plus all their dependencies add a following class to your vsix:

public class MyProjectWizard : IWizard
{
    IEnumerable<string> _packages;

    public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
    {
        if (customParams.Length > 0) {
            var vstemplate = XDocument.Load((string)customParams[0]);
            _packages = vstemplate.Root
                .ElementsNoNamespace("WizardData")
                .ElementsNoNamespace("packages")
                .ElementsNoNamespace("package")
                .Select(e => e.Attribute("id").Value)
                .ToList();
        }
    }

    public void ProjectFinishedGenerating(Project project)
    {
        var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
        var _installer = componentModel.GetService<IVsPackageInstaller2>();

        foreach (var package in _packages) {
            _installer.InstallLatestPackage(null, project, package, false, false);
        }
    }
}

And then use following in vstemplate:

  <WizardExtension>
    <Assembly>MyProjectWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=22c2a1a5fa7b6905</Assembly>
    <FullClassName>MyProjectWizard.MyProjectWizard</FullClassName>
  </WizardExtension>
like image 22
Poma Avatar answered Sep 19 '22 15:09

Poma