How to: Use Wizards with Project Templates

Visual Studio provides the IWizard interface that, when implemented, enables you to run custom code when a user creates a project from a template.

Project template customization can be used to:

  • Display custom UI that collects user input to parameterize the template.

  • Add parameter values to use in the template.

  • Add additional files to the template.

  • Perform virtually any action allowed by the Visual Studio automation object model on a project.

The IWizard interface methods are called at various times while the project is being created, starting as soon as a user clicks OK on the New Project dialog box. Each method of the interface is named to describe the point at which it is called. For example, Visual Studio calls RunStarted immediately when it starts to create the project, making it a good location to write custom code to collect user input.

Most of the code that you write for custom wizards will use the DTE object, which is the main object in the Visual Studio automation object model, to customize the project. For more information on the automation object model, see Extending the Visual Studio Environment and Automation and Extensibility Reference.

Creating a Custom Template Wizard

This topic shows how to create a custom wizard that opens a Windows Form before the project is created. The form allows the user to add a custom parameter value that will then be added to the source code during project creation. The main steps, each of which is explained in detail, are as follows.

To create a custom template wizard

  1. Create an assembly that implements the IWizard interface.

  2. Install the assembly into the global assembly cache.

  3. Create a project and use the Export Template wizard to create a template from the project.

  4. Modify the template by adding a WizardExtension element in the .vstemplate file to link the template to the assembly that implements IWizard.

  5. Create a new project using the custom wizard.

Implementing IWizard

The first step in the process is to create an assembly that implements IWizard. This assembly uses the RunStarted method to display a Windows Form that allows the user to add a custom parameter value, which will then be used during project creation.

Note

This example uses Visual C# to implement IWizard, although you could also use Visual Basic.

To implement IWizard

  1. Create a new class library project.

  2. Create a class that implements the IWizard interface. See the code below for a Visual C# example of a fully implemented IWizard interface.

This example contains two code files: IWizardImplementation, a class that implements the IWizard interface, and UserInputForm, the Windows Form for user input.

IWizardImplementation Class

The IWizardImplementation class contains method implementations for every member of IWizard. In this example, only the RunStarted method performs a task. All other methods either do nothing or return true.

The RunStarted method accepts four parameters:

  • An Object parameter that can be cast to the root _DTE object, to enable you to customize the project.

  • A Dictionary<TKey, TValue> parameter that contains a collection of all pre-defined parameters in the template. For more information on template parameters, see Template Parameters.

  • A WizardRunKind parameter that contains information about what kind of template is being used.

  • An Object array that contains a set of parameters passed to the wizard by Visual Studio.

This example adds a parameter value from the user input form to the Dictionary<TKey, TValue> parameter. Every instance of the $custommessage$ parameter in the project will be replaced with the text entered by the user.

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

namespace CustomWizard
{
    public class IWizardImplementation:IWizard
    {
        private UserInputForm inputForm;
        private string customMessage;

        // 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)
        {
            try
            {
                // Display a form to the user. The form collects 
                // input for the custom message.
                inputForm = new UserInputForm();
                inputForm.ShowDialog();

                customMessage = inputForm.get_CustomMessage();

                // Add custom parameters.
                replacementsDictionary.Add("$custommessage$", 
                    customMessage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

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

User Input Form

The user input form provides a simple form for entering a custom parameter. The form contains a text box named textBox1 and a button named button1. When the button is clicked, the text from the text box is stored in the customMessage parameter.

To add a Windows Form to the solution

  1. On the Project menu, click Add New Item.

  2. Click Windows Form, name the file UserInputForm.cs, and click OK.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CustomWizard
{
    public partial class UserInputForm : Form
    {
        private string customMessage;

        public UserInputForm()
        {
            InitializeComponent();
        }
       
        public string get_CustomMessage()
        {
            return customMessage;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            customMessage = textBox1.Text;

            this.Dispose();
        }
    }
}

Installing the Assembly into the Global Assembly Cache

The assembly that implements IWizard must be signed with a strong name and installed into the global assembly cache.

To install the assembly into the global assembly cache

  1. Sign the assembly with a strong name. For more information, see How to: Sign an Assembly with a Strong Name or How to: Sign an Assembly (Visual Studio).

  2. Install the strong-named assembly into the global assembly cache. For more information, see How to: Install an Assembly into the Global Assembly Cache.

Creating a Project to Use as a Template

In this example, the project used as the template is a console application that displays the message specified in the user input form of the custom wizard.

To create the example project

  1. Create a new Visual C# console application.

  2. In the Main method of the application, add the following line of code.

    Console.WriteLine("$custommessage$");
    

    The parameter $custommessage$ is replaced with the text entered in the user input form when a project is created from the template.

  3. On the File menu, click Export Template.

  4. In the Export Template wizard, click Project Template, select the correct project, and click Next.

  5. In the Export Template wizard, enter descriptive information about the template, select the Automatically import the template into Visual Studio check box, and click Finish.

    The template now appears in the New Project dialog box, but does not use the custom wizard.

The following example shows the full code file before it has been exported to a template.

using System;
using System.Collections.Generic;
using System.Text;

namespace TemplateProject
{
    class WriteMessage
    {
        static void Main(string[] args)
        {
            Console.WriteLine("$custommessage$");
        }
    }
}

Modifying the Template

Now that the template is created and appears in the New Project dialog box, you must modify it so that it uses the assembly that you created in the preceding steps.

To add the custom wizard to the template

  1. Locate the .zip file that contains the template.

    1. On the Tools menu, click Options.

    2. Click Projects and Solutions.

    3. Read the Visual Studio user project templates location text box. For more information, see General, Projects and Solutions, Options Dialog Box.

    By default, this location is My Documents\Visual Studio 2010\Templates\ProjectTemplates.

  2. Extract the .zip file.

  3. Open the .vstemplate file in Visual Studio.

  4. After the TemplateContent element, add a WizardExtension Element (Visual Studio Templates) element with the strong name of your custom wizard assembly. For more information on finding the strong name of your assembly, see How to: View the Contents of the Global Assembly Cacheand How to: Reference a Strong-Named Assembly.

    The following example shows a WizardExtension element.

    <WizardExtension>
        <Assembly>CustomWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=fa3902f409bb6a3b</Assembly>
        <FullClassName>CustomWizard.IWizardImplementation</FullClassName>
    </WizardExtension>
    

Using the Custom Wizard

Now you can create a project from your template and use the custom wizard.

To use the custom wizard

  1. On the File menu, click New Project.

  2. In the New Project dialog box, locate your template, type a name, and click OK.

    The wizard user input form opens.

  3. Type a value for the custom parameter and click the button.

    The wizard user input form closes, and a project is created from the template.

  4. In Solution Explorer, right-click the source code file and click View Code.

    Notice that $custommessage$ has been replaced with the text entered in the wizard user input form.

See Also

Reference

WizardExtension Element (Visual Studio Templates)

IWizard

Other Resources

Advanced Template Procedures