ligershark / sidewafflev2

Other
30 stars 11 forks source link

Wizard RunFinished runs at wrong time #39

Closed Pietervdw closed 5 years ago

Pietervdw commented 5 years ago

Hi Guys,

I've created a multi-project template using the SideWaffle Creator. Everything works perfectly, so I add a custom wizard that implements IWizard and I add it to the template.vstemplate file:

  <WizardExtension>
    <Assembly>MyTemplate.Wizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</Assembly>
    <FullClassName>MyTemplate.Wizard.ProjectWizard</FullClassName>
  </WizardExtension>

When I run the template (File > New Project) the RunStarted event on the IWizard class runs fine:

private DTE dte = null;
public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary,
    WizardRunKind runKind, object[] customParams)
{
    if (automationObject is DTE)
        dte = (DTE)automationObject;
}

But it looks like the RunFinished method runs immediately after RunStarted:

public void RunFinished()
{
    var solution = dte.Solution;
    var projects = solution.Projects; // solution.Projects.Count = 0
}

The project is also only generated after the RunFinished method is called. This means that I can't run any project specific code after the wizard finishes, since any project in the solution is essentially null. Using the "old" TemplateBuilder way this approach used to work fine. Not sure if I'm missing anything

Any advice would be highly appreciated. Many Thanks!

sayedihashimi commented 5 years ago

@phenning this is in reference to Microsoft.VisualStudio.TemplateEngine.Wizard.TemplateEngineWizard, can you comment?

phenning commented 5 years ago

Order of declaration in the vstemplate file is important.

Given the following:

  <WizardExtension>
    <Assembly>MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>MyAssembly.BeforeWizard</FullClassName>
  </WizardExtension>
  <WizardExtension>
    <Assembly>Microsoft.VisualStudio.TemplateEngine.Wizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>Microsoft.VisualStudio.TemplateEngine.Wizard.TemplateEngineWizard</FullClassName>
  </WizardExtension>
  <WizardExtension>
    <Assembly>MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>MyAssembly.AfterWizard</FullClassName>
  </WizardExtension>   

The expected order of calling is as follows:

BeforeWizard.RunStarted 
TemplateEngineWizard.RunStarted
AfterWizard.RunStarted

BeforeWizard.ProjectFinishedGenerating
TemplateEngineWizard.ProjectFinishedGenerating  
AfterWizard.ProjectFinishedGenerating

BeforeWizard.RunFinished 
TemplateEngineWizard.RunFinished
AfterWizard.RunFinished

BeforeWizard.RunStarted is where you would want to hook in to modify the replacementsDictionary and/or invoke a custom UI. You may want to do this in order to supply a groupid or templateid via the dictionary to pass to the TemplateEngineWizard when $uistyle$=none is specified as a custom parameter: <CustomParameter Name="$uistyle$" Value="none" />

TemplateEngineWizard.RunStarted is where the UI is invoked for web projects, or in the case of when $uistyle$ = none is specified where we determine which template should be created. This is based on the $groupid$ and $templateid$ parameters passed via the vstemplate file's CustomParameter, or inserted in your BeforeWizard.RunStarted.

TemplateEngineWizard.RunFinished is where the template is actually created and added to the solution.

AfterWizard.RunFinished is where you could access the created solution and project via DTE.

Additionally, you'll also want to ensure that the vstemplate file specifies "ProjectGroup": <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">

Let me know if you have any other questions.

Pietervdw commented 5 years ago

Thank you @phenning for your detailed explanation, its great. I've made the changes as you described and it works 100% as expected. Thank you very much!