プロジェクト テンプレートでウィザードを使用する

Visual Studio には、IWizard インターフェイスが用意されています。このインターフェイスを実装すると、ユーザーがテンプレートからプロジェクトを作成する際にカスタム コードを実行できるようになります。

プロジェクト テンプレートのカスタマイズを使用すると、ユーザー入力を収集してテンプレートをカスタマイズしたり、テンプレートにファイルを追加したり、プロジェクトで許可されているその他のアクションを実行したりするカスタム UI を表示できます。

IWizard インターフェイス メソッドは、プロジェクトの作成中にさまざまな時点で呼び出されます。プロジェクトの作成は、ユーザーが [新しいプロジェクト] ダイアログ ボックスの [OK] をクリックすると同時に開始されます。 インターフェイスの各メソッドには、そのメソッドが呼び出される時点を表す名前が付けられます。 たとえば、プロジェクトの作成の開始直後に、Visual Studio によって RunStarted が呼び出されます。この時点が、ユーザー入力を収集するためのカスタム コードの記述に適した場所になります。

VSIX プロジェクトを使用してプロジェクト テンプレート プロジェクトを作成する

カスタム テンプレートの作成は、Visual Studio SDK の一部であるプロジェクト テンプレート プロジェクトから始めます。 この手順では、C# プロジェクト テンプレート プロジェクトを使用しますが、Visual Basic プロジェクト テンプレート プロジェクトもあります。 次に、プロジェクト テンプレート プロジェクトを含むソリューションに VSIX プロジェクトを追加します。

  1. C# プロジェクト テンプレート プロジェクトを作成します (Visual Studio で、[ファイル]>[新規]>[プロジェクト] を選択し、「プロジェクト テンプレート」を検索します)。 MyProjectTemplate と名前を付けます。

    Note

    Visual Studio SDK のインストールを求められる場合があります。 詳細については、「Visual Studio SDK のインストール」を参照してください。

  2. プロジェクト テンプレート プロジェクトと同じソリューションに新しい VSIX プロジェクトを追加します (ソリューション エクスプローラーで、ソリューション ノードを選択し、右クリックして、[追加]>[新しいプロジェクト] を選択し、「vsix」を検索します)。 MyProjectWizard と名前を付けます。

  3. VSIX プロジェクトをスタートアップ プロジェクトとして設定します。 ソリューション エクスプローラーで VSIX プロジェクト ノードを選択し、右クリックして、[スタートアップ プロジェクトに設定] を選択します。

  4. テンプレート プロジェクトを VSIX プロジェクトのアセットとして追加します。 ソリューション エクスプローラーの VSIX プロジェクト ノードで、source.extension.vsixmanifest ファイルを見つけます。 それをダブルクリックしてマニフェスト エディターで開きます。

  5. マニフェスト エディターで、ウィンドウの左側にある [アセット] タブを選択します。

  6. [アセット] タブで、[新規] を選択します。 [新しい資産の追加] ウィンドウの [種類] フィールドで [Microsoft.VisualStudio.ProjectTemplate] を選択します。 [ソース] フィールドで、[現在のソリューション内のプロジェクト] を選択します。 [プロジェクト] フィールドで、[MyProjectTemplate] を選択します。 OK をクリックします。

  7. ソリューションをビルドし、デバッグを開始します。 Visual Studio の 2 番目のインスタンスが表示されます。 (これには数分かかることがあります)。

  8. Visual Studio の 2 番目のインスタンスで、新しいテンプレートを使用して新しいプロジェクトを作成してみてください ([ファイル]>[新規]>[プロジェクト] を選択し、「myproject」を検索します)。 Class1 という名前のクラスがある新しいプロジェクトが表示されます。 これでカスタム プロジェクト テンプレートの作成は完了です。 すぐにデバッグを停止してください。

カスタム テンプレート ウィザードを作成する

この手順では、プロジェクトを作成する前に Windows フォームを開くカスタム ウィザードを作成する方法について説明します。 このフォームを使用すると、ユーザーは、プロジェクトの作成時にソース コードに追加されるカスタム パラメーター値を追加できます。

  1. アセンブリを作成できるように VSIX プロジェクトを設定します。

  2. ソリューション エクスプローラーで VSIX プロジェクト ノードを選択します。 ソリューション エクスプローラーの下にプロパティ ウィンドウが表示されます。 そうでない場合は、[表示]>[プロパティ ウィンドウ] を選択するか、F4 キーを押します。 プロパティ ウィンドウでは、次のフィールドに true を選択します。

    • [Include Assembly in VSIX Container] (VSIX コンテナーにアセンブリを含める)

    • [Include Debug Symbols in Local VSIX Deployment] (ローカルの VSIX 配置にデバッグ シンボルを含める)

    • [Include Debug Symbols in VSIX Container] (VSIX コンテナーにデバッグ シンボルを含める)

  3. アセンブリをアセットとして VSIX プロジェクトに追加します。 source.extension.vsixmanifest ファイルを開き、[資産] タブを選択します。[新しい資産の追加] ウィンドウで、[種類][Microsoft.VisualStudio.Assembly] を選択し、[ソース][現在のソリューション内のプロジェクト] を選択し、[プロジェクト][MyProjectWizard] を選択します。

  4. 以下の参照を VSIX プロジェクトに追加します (ソリューション エクスプローラーの VSIX プロジェクト ノードで、[参照] を選択し、右クリックして、[参照の追加] を選択します)。[参照の追加] ダイアログの [フレームワーク] タブで、System.Windows フォーム アセンブリを見つけて選択します。 また、SystemSystem.Drawing の各アセンブリを見つけて選択します。 次に、[拡張機能] タブを選択します。EnvDTE アセンブリを見つけて選択します。 また、Microsoft.VisualStudio.TemplateWizardInterface アセンブリを見つけて選択します。 OK をクリックします。

  5. ウィザード実装のクラスを VSIX プロジェクトに追加します (ソリューション エクスプローラーで、VSIX プロジェクト ノードを右クリックし、[追加][新しい項目][クラス] の順に選択します)。クラスに WizardImplementation と名前を付けます。

  6. WizardImplementationClass.cs ファイルのコードを次のコードに置き換えます。

    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TemplateWizard;
    using System.Windows.Forms;
    using EnvDTE;
    
    namespace MyProjectWizard
    {
        public class WizardImplementation: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 = UserInputForm.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;
            }
        }
    }
    

    このコードで参照されている UserInputForm は、後で実装されます。

    WizardImplementation クラスには、IWizard のすべてのメンバーに対するメソッドの実装が含まれています。 この例では、RunStarted メソッドだけがタスクを実行します。 他のすべてのメソッドは、何もしないか、true を返します。

    RunStarted メソッドは、次の 4 つのパラメーターを受け取ります。

    • Object パラメーター。プロジェクトをカスタマイズできるように、ルートの _DTE オブジェクトにキャストできます。

    • Dictionary<TKey,TValue> パラメーター。テンプレートで定義済みのすべてのパラメーターのコレクションが含まれます。 テンプレート パラメーターの詳細については、「テンプレート パラメーター」を参照してください。

    • WizardRunKind パラメーター。使用されているテンプレートの種類に関する情報が含まれます。

    • Object 配列。Visual Studio によってウィザードに渡される一連のパラメーターが格納されます。

      この例では、ユーザー入力フォームから Dictionary<TKey,TValue> パラメーターにパラメーター値を追加します。 プロジェクト内の $custommessage$ パラメーターのすべてのインスタンスは、ユーザーが入力したテキストと置き換えられます。

  7. 次に、UserInputForm を作成します。 WizardImplementation.cs ファイルで、WizardImplementation クラスの末尾の後に次のコードを追加します。

    public partial class UserInputForm : Form
        {
            private static string customMessage;
            private TextBox textBox1;
            private Button button1;
    
            public UserInputForm()
            {
                this.Size = new System.Drawing.Size(155, 265);
    
                button1 = new Button();
                button1.Location = new System.Drawing.Point(90, 25);
                button1.Size = new System.Drawing.Size(50, 25);
                button1.Click += button1_Click;
                this.Controls.Add(button1);
    
                textBox1 = new TextBox();
                textBox1.Location = new System.Drawing.Point(10, 25);
                textBox1.Size = new System.Drawing.Size(70, 20);
                this.Controls.Add(textBox1);
            }
            public static string CustomMessage
            {
                get
                {
                    return customMessage;
                }
                set
                {
                    customMessage = value;
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                customMessage = textBox1.Text;
                this.Close();
            }
        }
    

    ユーザー入力フォームには、カスタム パラメーターを入力するための簡単なフォームが用意されています。 このフォームには、textBox1 という名前のテキスト ボックスおよび button1 という名前のボタンがあります。 このボタンをクリックすると、テキスト ボックスのテキストが customMessage パラメーターに格納されます。

ウィザードをカスタム テンプレートに接続する

カスタム プロジェクト テンプレートでカスタム ウィザードを使用するには、ウィザード アセンブリに署名し、カスタム プロジェクト テンプレートにいくつかの行を追加して、新しいプロジェクトが作成されたときにウィザードの実装がどこにあるかを把握できるようにする必要があります。

  1. アセンブリにサインします。 ソリューション エクスプローラーで、VSIX プロジェクトを選択し、右クリックして、[プロジェクトのプロパティ] を選択します。

  2. [プロジェクトのプロパティ] ウィンドウで、[署名] タブを選択します。[署名] タブで、[アセンブリの署名] を確認します。 厳密な名前のキー ファイルを選択するフィールドで、<新規>を選択します。 [厳密な名前キーの作成] ウィンドウの [キー ファイル名] フィールドに「key.snk」と入力します。 [キーファイルをパスワードで保護する] フィールドをオフにします。

  3. ソリューション エクスプローラーで、VSIX プロジェクトを選択し、[プロパティ] ウィンドウを見つけます。

  4. [Copy Build Output to Output Directory]\(ビルド出力を出力ディレクトリにコピーする\) フィールドを [true] に設定します。 これにより、ソリューションのリビルド時にアセンブリが出力ディレクトリにコピーされるようになります。 これはまだ .vsix ファイルに含まれています。 署名キーを調べるには、アセンブリを確認する必要があります。

  5. ソリューションをリビルドします。

  6. これで、MyProjectWizard プロジェクト ディレクトリで key.snk ファイル (<ご使用のディスクの場所>\MyProjectTemplate\MyProjectWizard\key.snk) を見つけることができます。 key.snk ファイルをコピーします。

  7. 出力ディレクトリに移動し、アセンブリ (<ご使用のディスクの場所>\MyProjectTemplate/MyProjectWizard\bin\Debug\MyProjectWizard.dll) を見つけます。 key.snk ファイルをここに貼り付けます (これは絶対に必要というわけではありませんが、次の手順が簡単になります)。

  8. コマンド ウィンドウを開き、アセンブリが作成されたディレクトリに移動します。

  9. sn.exe 署名ツールを見つけます。 たとえば、Windows 10 64 ビット オペレーティング システムでは、一般的なパスは次のようになります。

    C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools

    ツールが見つからない場合は、コマンド ウィンドウで where /R . sn.exe を実行してみてください。 パスをメモします。

  10. key.snk ファイルから公開キーを抽出します。 コマンド ウィンドウで、次のように入力します

    <sn.exe の場所>\sn.exe -p key.snk outfile.key.

    ディレクトリ名にスペースがある場合は、sn.exe のパスを必ず引用符で囲んでください。

  11. 出力ファイルから公開キー トークンを取得します。

    <sn.exe の場所>\sn.exe -t outfile.key.

    繰り返しになりますが、引用符を忘れないでください。 次のような行が出力に表示されます。

    Public key token is <token> (公開キー トークンは <トークン> です)

    この値を書き留めておきます。

  12. カスタム ウィザードへの参照をプロジェクト テンプレートの .vstemplate ファイルに追加します。 ソリューション エクスプローラーで、MyProjectTemplate.vstemplate という名前のファイルを見つけて開きます。 <TemplateContent> セクションの末尾の後に、次のセクションを追加します。

    <WizardExtension>
        <Assembly>MyProjectWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=token</Assembly>
        <FullClassName>MyProjectWizard.WizardImplementation</FullClassName>
    </WizardExtension>
    

    この MyProjectWizard はアセンブリの名前であり、token は前の手順でコピーしたトークンです。

  13. プロジェクト内のすべてのファイルを保存してリビルドします。

テンプレートにカスタム パラメーターを追加する

この例で、テンプレートとして使用されるプロジェクトには、カスタム ウィザードのユーザー入力フォームに指定されたメッセージが表示されます。

  1. ソリューション エクスプローラーで、MyProjectTemplate プロジェクトに移動し、Class1.cs を開きます。

  2. アプリケーションの Main メソッドに次のコード行を追加します。

    Console.WriteLine("$custommessage$");
    

    $custommessage$ パラメーターは、プロジェクトをテンプレートから作成する際にユーザー入力フォームに入力したテキストで置き換えられます。

テンプレートにエクスポートされる前の完全なコード ファイルを次に示します。

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;

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

カスタム ウィザードを使用する

これで、テンプレートからプロジェクトを作成し、カスタム ウィザードを使用できるようになりました。

  1. ソリューションをリビルドし、デバッグを開始します。 Visual Studio の 2 番目のインスタンスが表示されます。

  2. 新しい MyProjectTemplate プロジェクトを作成します ([ファイル]>[新規]>[プロジェクト])。

  3. [新しいプロジェクト] ダイアログ ボックスで「myproject」を検索してテンプレートを見つけ、名前を入力し、[OK] をクリックします。

    ウィザードのユーザー入力フォームが開きます。

  4. カスタム パラメーターの値を入力し、ボタンをクリックします。

    ウィザードのユーザー入力フォームが終了し、プロジェクトがテンプレートから作成されます。

  5. ソリューション エクスプローラーで、ソース コード ファイルを右クリックし、[コードの表示] をクリックします。

    $custommessage$ は、ウィザードのユーザー入力フォームに入力されたテキストで置き換えられています。