Visual Studio 提供了 IWizard 接口,在实现该接口后,您可以在用户根据模板创建项目时运行自定义代码。
项目模板的自定义可用于:
- 显示收集用户输入以参数化模板的自定义 UI。 
- 添加要在模板中使用的参数值。 
- 向模板添加其他文件。 
- 执行项目的 Visual Studio 自动化对象模型允许的几乎任何操作。 
在创建项目过程中的各个时间(从用户单击**“新建项目”对话框上的“确定”**开始)都会调用 IWizard 接口方法。 接口的每个方法都被命名以描述调用该方法的时刻。 例如,当 Visual Studio 开始创建项目时,它立即调用 RunStarted,这使其成为编写自定义代码以收集用户输入的一个良好位置。
为自定义向导编写的大多数代码将使用 DTE 对象(它是 Visual Studio 自动化对象模型中的主对象)来自定义项目。 有关自动化对象模型的更多信息,请参见扩展 Visual Studio 环境和自动化与扩展性参考。
创建自定义模板向导
本主题显示如何创建一个自定义向导,该向导在创建项目之前打开一个 Windows 窗体。 此窗体允许用户添加自定义参数值,此值随后在创建项目的过程中被添加到源代码中。 主要步骤如下所示,其中每一步都有详细解释。
创建自定义模板向导
- 创建实现 IWizard 接口的程序集。 
- 将此程序集安装到全局程序集缓存中。 
- 创建一个项目并使用**“导出模板”**向导根据该项目创建模板。 
- 通过在 .vstemplate 文件中添加 WizardExtension 元素来修改模板,以将此模板链接到实现 IWizard 的程序集。 
- 使用自定义向导创建新项目。 
实现 IWizard
此过程的第一步是创建实现 IWizard 的程序集。 此程序集使用 RunStarted 方法显示一个 Windows 窗体,该窗体允许用户添加一个自定义参数值,随后将在创建项目的过程中使用此值。
提示
本示例使用 Visual C# 实现 IWizard,但您也可以使用 Visual Basic。
实现 IWizard
本示例包含两个代码文件:IWizardImplementation,它是一个实现 IWizard 接口的类;以及 UserInputForm,它是用于获得用户输入的 Windows 窗体。
IWizardImplementation 类
IWizardImplementation 类包含 IWizard 的每个成员的方法实现。 在本示例中,只有 RunStarted 方法执行任务。 所有其他方法要么不执行任何任务,要么返回 true。
RunStarted 方法接受四个参数:
- Dictionary<TKey, TValue> 参数,它包含模板中所有预定义参数的集合。 有关模板参数的更多信息,请参见 模板参数。 
- WizardRunKind 参数,它包含有关所使用的模板种类的信息。 
- Object 数组,它包含通过 Visual Studio 传递给向导的一组参数。 
本示例将一个来自用户输入窗体的参数值添加到 Dictionary<TKey, TValue> 参数中。 项目中 $custommessage$ 参数的每个实例都将替换为用户输入的文本。
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;
        }        
    }
}
用户输入窗体
用户输入窗体提供一个用于输入自定义参数的简单窗体。 该窗体包含一个名为 textBox1 的文本框和一个名为 button1 的按钮。 单击此按钮时,文本框中的文本将存储在 customMessage 参数中。
向解决方案添加 Windows 窗体
- 在**“项目”菜单上,单击“添加新项”**。 
- 单击**“Windows 窗体”,将文件命名为 UserInputForm.cs,然后单击“确定”**。 
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();
        }
    }
}
将程序集安装到全局程序集缓存中
必须用强名称对实现 IWizard 的程序集进行签名,并将该程序集安装到全局程序集缓存中。
将程序集安装到全局程序集缓存中
- 用强名称对程序集进行签名。 有关更多信息,请参见如何:使用强名称为程序集签名或如何:对程序集进行签名 (Visual Studio)。 
- 将强名称程序集安装到全局程序集缓存中。 有关更多信息,请参见如何:将程序集安装到全局程序集缓存。 
创建要用作模板的项目
在本示例中,用作模板的项目是一个控制台应用程序,它显示在自定义向导的用户输入窗体中指定的消息。
创建示例项目
- 创建一个新的 Visual C# 控制台应用程序。 
- 在应用程序的 Main 方法中,添加以下代码行。 - Console.WriteLine("$custommessage$");- 当根据模板创建项目时,参数 $custommessage$ 将替换为在用户输入窗体中输入的文本。 
- 在**“文件”菜单上,单击“导出模板”**。 
- 在**“导出模板”向导中,单击“项目模板”,选择正确的项目,然后单击“下一步”**。 
- 在**“导出模板”向导中,输入关于该模板的描述性信息,选择“自动将模板导入到 Visual Studio 中”复选框,然后单击“完成”**。 - 现在,模板显示在**“新建项目”**对话框中,但没有使用自定义向导。 
下面的示例显示导出到模板之前的完整代码文件。
using System;
using System.Collections.Generic;
using System.Text;
namespace TemplateProject
{
    class WriteMessage
    {
        static void Main(string[] args)
        {
            Console.WriteLine("$custommessage$");
        }
    }
}
修改模板
现在,模板已被创建并显示在**“新建项目”**对话框中,必须对其进行修改,以便它使用在前面步骤中创建的程序集。
向模板添加自定义向导
- 找到包含该模板的 .zip 文件。 - 在**“工具”菜单上,单击“选项”**。 
- 单击**“项目和解决方案”**。 
- 读取**“Visual Studio 用户项目模板位置”**文本框。 有关更多信息,请参见“选项”对话框 ->“项目和解决方案”->“常规”。 
 - 默认情况下,此位置为 My Documents\Visual Studio 2010\Templates\ProjectTemplates。 
- 解压缩该 .zip 文件。 
- 在 Visual Studio 中打开 .vstemplate 文件。 
- 在 TemplateContent 元素后,添加具有自定义向导程序集的强名称的 WizardExtension 元素(Visual Studio 模板) 元素。 有关查找程序集的强名称的更多信息,请参见如何:查看全局程序集缓存的内容和如何:引用具有强名称的程序集。 - 下面的示例显示一个 WizardExtension 元素。 - <WizardExtension> <Assembly>CustomWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=fa3902f409bb6a3b</Assembly> <FullClassName>CustomWizard.IWizardImplementation</FullClassName> </WizardExtension>
使用自定义向导
现在,您可以根据自己的模板创建项目并使用自定义向导。
使用自定义向导
- 在**“文件”菜单上,单击“新建项目”**。 
- 在**“新建项目”对话框中,定位您的模板,键入名称,然后单击“确定”**。 - 向导用户输入窗体将打开。 
- 为自定义参数键入一个值并单击按钮。 - 向导用户输入窗体将关闭,并且根据模板创建了一个项目。 
- 在**“解决方案资源管理器”中,右击源代码文件并单击“查看代码”**。 - 请注意,$custommessage$ 已替换为在向导用户输入窗体中输入的文本。 
请参见
参考
WizardExtension 元素(Visual Studio 模板)