Search code examples
c#visual-studio-2013vsixproject-templatemulti-project

Using multiple IWizard implementations in ProjectTemplates


I am creating a multi-project solution template for my organization that requires both Nuget packages to be installed and some custom parameters to be set using a Windows Form upon creation. I am deploying it using a VSIX.

I have both these features running separately, but I have not found a way to use both at the same time. According to http://msdn.microsoft.com/en-us/library/vstudio/bb763141(v=vs.100).aspx Visual Studio should support the use of more than one IWizard in a project template, if I'm understanding it correctly.

I have tried the direct approach and just adding the reference to both wizards in the .vstemplate-file, but only the first is executed. I have also tried to call the Nuget-wizard within my custom Wizard by using the code below, but I guess I have to set the WizardData with the packages-info somehow for this to work...

var asm = Assembly.Load("NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
var nuget = (IWizard)asm.CreateInstance("NuGet.VisualStudio.TemplateWizard");
nuget.RunStarted(automationObject, replacementsDictionary, runKind, customParams);

Can the use of multiple IWizard-implementations be achieved or is this not possible?


Solution

  • no, you cannot register more than one IWizard derived class per template, in the case of nuget, you can callit by reflection like this:

    private void AddNugetPackage(VSProject VsProj, string PackageName, string Version)
        {
          try
          {
            Assembly nugetAssembly = Assembly.Load("nuget.core");
            Type packageRepositoryFactoryType = nugetAssembly.GetType("NuGet.PackageRepositoryFactory");
            PropertyInfo piDefault = packageRepositoryFactoryType.GetProperty("Default");
            MethodInfo miCreateRepository = packageRepositoryFactoryType.GetMethod("CreateRepository");
            object repo = miCreateRepository.Invoke(piDefault.GetValue(null, null), new object[] { "https://packages.nuget.org/api/v2" });
            Type packageManagerType = nugetAssembly.GetType("NuGet.PackageManager");
            ConstructorInfo ciPackageManger = packageManagerType.GetConstructor(new Type[] { System.Reflection.Assembly.Load("nuget.core").GetType("NuGet.IPackageRepository"), typeof(string) });
            DirectoryInfo di = new DirectoryInfo(ProjectPath);
            string solPath = di.Parent.FullName;
            string installPath = di.Parent.CreateSubdirectory("packages").FullName;
            object packageManager = ciPackageManger.Invoke(new object[] { repo, installPath });
            MethodInfo miInstallPackage = packageManagerType.GetMethod("InstallPackage",
              new Type[] { typeof(string), System.Reflection.Assembly.Load("nuget.core").GetType("NuGet.SemanticVersion") });
            string packageID = PackageName;
            MethodInfo miParse = nugetAssembly.GetType("NuGet.SemanticVersion").GetMethod("Parse");
            object semanticVersion = miParse.Invoke(null, new object[] { Version });
            miInstallPackage.Invoke(packageManager, new object[] { packageID, semanticVersion });
          }
          catch(Exception ex)
          { 
            // ...
            return;
          }      
        }