Search code examples
c#vsixvisual-studio-templates

How to stop the wizard operation (IWizard) in Project Template concept


I have one project template with the wizard concept. When choosing the Template, it will show the wizard to configure the product.

The wizard contains two buttons

1.Finish

2.Cancel

When the finish button is clicked I want to generate the project based on the option chosen in the wizard. This one I have already done using the wizard concept in the project template.

When the Cancel button is clicked I want to stop the project generation and close the wizard simply. how can I stop the project generation and close the wizard without any exception?

using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TemplateWizard;
using System.Windows.Forms;
using EnvDTE;

namespace MyProjectWizard
{
    public class WizardImplementation : IWizard
    {

        public TeamsForm firstForm;
        //This method is called before opening any item that
        // has the OpenInEditor attribute.
        public void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public void ProjectFinishedGenerating(Project project)
        {
        }

        // This method is only called for item templates,
        // not for project templates.
        public void ProjectItemFinishedGenerating(ProjectItem
            projectItem)
        {
        }

        // This method is called after the project is created.
        public void RunFinished()
        {
        }

        public void RunStarted(object automationObject,
            Dictionary<string, string> replacementsDictionary,
            WizardRunKind runKind, object[] customParams)
        {
            firstForm = new TeamsForm();
            firstForm.ShowDialog();
        }

        // This method is only called for item templates,
        // not for project templates.
        public bool ShouldAddProjectItem(string filePath)
        {
            return true;
        }
    }
}

Solution

  • There is only one way to do it without you throwing an exception. That is via the IDTWizard interface. This is not as straightforward though: https://learn.microsoft.com/en-us/previous-versions/7k3w6w59(v=vs.140)?redirectedfrom=MSDN

    In your case I would go with something like this:https://www.neovolve.com/2011/07/19/pitfalls-of-cancelling-a-vsix-project-template-in-an-iwizard/

    public void RunStarted(
        Object automationObject, Dictionary<String, String> replacementsDictionary, WizardRunKind runKind, Object[] customParams)
    {
        DTE dte = automationObject as DTE;
    
        String destinationDirectory = replacementsDictionary["$destinationdirectory$"];
    
        try
        {
            using (PackageDefinition definition = new PackageDefinition(dte, destinationDirectory))
            {
                DialogResult dialogResult = definition.ShowDialog();
    
                if (dialogResult != DialogResult.OK)
                {
                    throw new WizardBackoutException();
                }
    
                replacementsDictionary.Add("$packagePath$", definition.PackagePath);
                replacementsDictionary.Add("$packageExtension$", Path.GetExtension(definition.PackagePath));
    
                _dependentProjectName = definition.SelectedProject;
            }
        }
        catch (Exception ex)
        {
            // Clean up the template that was written to disk
            if (Directory.Exists(destinationDirectory))
            {
                Directory.Delete(destinationDirectory, true);
            }
    
            Debug.WriteLine(ex);
    
            throw;
        }
    }