有時建立Project 或Item 時, 除了預設名字外, 可能有需要加入更多的參數(Parameter)讓development 更方便, 在Project / item 生成後不用走入去再修改. 在這裡, 會示範如何在Project Template 中加入Wizard.
- 先找來一個Project Temple, 為方便示範, 故直接建立一個Project Template.
按File->New->Project, 選擇Installed->Templates->Visual C#->Extensibility, 選取C# Project Template. 在是次示範, Project 命名為TestProjectTemplate.
- 於Project Template 中建立一個VSIX Project 作Wizard.
按File->New->Project, 選擇Installed->Templates->Visual C#->Extensibility, 選取VSIX Project. 在是次示範, Project 命名為ProjectWizard.
- 將ProjectWizard 設為Startup Project.
於ProjectWizard 右按, 選取Set as StartUp Project.
- 加入Project Template 作 VSIX asset.
開啟source.extension.vsixmanifest, 選取Asset, 按New, 於Type 中選擇Microsoft.VisualStudio.ProjectTemplate, Source 選擇A project in current solution, 於Project 中選擇TestProjectTemplate. 然後按OK.
- 於ProjectWizard 中, 選擇Property, 並將以下設定改為True.
Copy Build Output to Output Directory;
Copy Debug Symbol to Output Directory;
Include Assembly in VSIX Container;
Include Debug Symbols in Local Deployment;
Include Debug Symbols in CSIZ Container;
- 將ProjectWizard 加到Asset 中, 使在project create 時能夠透過XML call.
開啟source.extension.vsixmanifest, 選取Asset, 按New, 於Type 中選擇Microsoft.VisualStudio.Assembly, Source 選擇A project in current solution, 於Project 中選擇ProjectWizard. 然後按OK.
- 於ProjectWizard 中建立一個class, 命名為WizardImplementation, 並貼上以以下的code.
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; } }
- 於ProjectWizard 中建立另一個class名為UserInputForm, 作為Wizard 的UI.
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.Text = "Add text here."; 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(); } }
- 建立Key作Template與Project 的聯繫. 於ProjectWizard Property 中, 選取Signing, 剔取Sign the assembly, 並於Choose a strong name key file 中選擇<<New…>>
- 開始建立key. 於Key file name 中輸入key.sln, 剔除Protect my key file with a password, Signature Algronithrom 選取SHA256RAS 後按OK.
- 將key.sln 複制到/bin/debug 內.
- 開啟Visual Studio Command Prompt, 再去到<<Project folder>>/ bin/debug 中執行以下指令.
### Generate Public Key. sn.exe - p key.snk outfile.key ### Get Public key token and export STDOUT to text file. sn.exe - t outfile.key > c:\STDOUT.txt
- 於TestProjectTemplate 中開啟TestProjectTemplate.vstemplate, 並於<TemplateContent>後加入以下element, 決定建立Project 時會call 的wizard. 而[[token]] 是於STDOUT.txt 中export 出來的value.
<WizardExtension> <Assembly>ProjectWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=[[token]]</Assembly> <FullClassName>ProjectWizard.WizardImplementation</FullClassName> </WizardExtension>
- 於TestProjectTemplate 中開啟Class1.cs, 並修改以下內容.
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$"); } } }
- 之後開始Debug, 之後會開一個新的Visual Studio Instance, 選擇New Project.
- 於Visual C# 中選取TestProjectTemplate, 然後按OK.
- 之前建立的UserInputForm 便會彈出, 輸入資料後按Add
- Porject 建立後, 開啟Class1.cs, 見到剛才輸入的字句的話, 測試成功.
Reference
Leave a Reply