上一篇,介绍了VSIX安装模板的方法,那么,你是不是要问,为何有些项目模板却可以有向导,那是怎么做到的
今天这篇文章就是介绍如何为自己的模板添加向导,向导可以引导你完成项目中各种参数的设置,比如项目创建人,项目描述,公司等
下图创建Web项目时的向导
下面我们开始制作我们自己的项目向导
需要用到的两个类库: envdte , Microsoft.VisualStudio.TemplateWizardInterface
创建一个类库项目,引用上面两个类库
添加一个类,取名ProjectWizard继承IWizard接口实现 RunStarted 方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using EnvDTE; using Microsoft.VisualStudio.TemplateWizard; namespace TemplateTestWizard { public class ProjectWizard:IWizard { private bool shouldAdd = true; public string Creator = ""; public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) { Creator = replacementsDictionary["$username$"]; AssemblyWizard wizard=new AssemblyWizard(this); if (wizard.ShowDialog() == DialogResult.OK) { replacementsDictionary["$username$"]=Creator; shouldAdd = true; } else { shouldAdd = false; } } public void ProjectFinishedGenerating(Project project) { } public void ProjectItemFinishedGenerating(ProjectItem projectItem) { } public bool ShouldAddProjectItem(string filePath) { return shouldAdd; } public void BeforeOpeningFile(ProjectItem projectItem) { } public void RunFinished() { } } }
下面为项目添加签名,由于制作的类库需要放到全局应用缓存中去,必须要添加签名
然后,打开Visual Studio命令提示符,以管理员运行,用 gacutil -i 注册生成的dll
gacutil -i path 注册程序集到全局应用程序缓存中 gacutil -l name 查看相应的程序集 gacutil -u name 卸载相应的程序集
下面,修改前面制作的Template,解压Template文件,打开 .vstemplate 文件,添加如下代码
<WizardExtension> <Assembly> TemplateTestWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2be8376f02202422, processorArchitecture=MSIL </Assembly> <FullClassName>TemplateTestWizard.ProjectWizard</FullClassName> </WizardExtension>
其中 Assembly 节点写的是内容可以用 gacutil -l name 查看,然后复制出来
FullClassName 是项目中ProjectWizard的完全限定名称
修改完模板后,在VS中打开新建项目
这个自定义向导就出来了,
如果模板里面有 $username$
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace $safeprojectname$ { /// <summary> /// 创建人:$username$ /// </summary> public static class CodeTimer { public static void Initialize() { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; Time("", 1, () => { }); } public static void Time(string name, int iteration, Action action) { if (String.IsNullOrEmpty(name)) return; // 1. ConsoleColor currentForeColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(name); // 2. GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); int[] gcCounts = new int[GC.MaxGeneration + 1]; for (int i = 0; i <= GC.MaxGeneration; i++) { gcCounts[i] = GC.CollectionCount(i); } // 3. Stopwatch watch = new Stopwatch(); watch.Start(); ulong cycleCount = GetCycleCount(); for (int i = 0; i < iteration; i++) action(); ulong cpuCycles = GetCycleCount() - cycleCount; watch.Stop(); // 4. Console.ForegroundColor = currentForeColor; Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms"); Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0")); // 5. for (int i = 0; i <= GC.MaxGeneration; i++) { int count = GC.CollectionCount(i) - gcCounts[i]; Console.WriteLine("\tGen " + i + ": \t\t" + count); } Console.WriteLine(); } private static ulong GetCycleCount() { ulong cycleCount = 0; QueryThreadCycleTime(GetCurrentThread(), ref cycleCount); return cycleCount; } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime); [DllImport("kernel32.dll")] static extern IntPtr GetCurrentThread(); } }
生成之后代码
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace ConsoleApplication25 { /// <summary> /// 创建人:Administrator /// </summary> public static class CodeTimer { public static void Initialize() { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; Time("", 1, () => { }); } public static void Time(string name, int iteration, Action action) { if (String.IsNullOrEmpty(name)) return; // 1. ConsoleColor currentForeColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(name); // 2. GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); int[] gcCounts = new int[GC.MaxGeneration + 1]; for (int i = 0; i <= GC.MaxGeneration; i++) { gcCounts[i] = GC.CollectionCount(i); } // 3. Stopwatch watch = new Stopwatch(); watch.Start(); ulong cycleCount = GetCycleCount(); for (int i = 0; i < iteration; i++) action(); ulong cpuCycles = GetCycleCount() - cycleCount; watch.Stop(); // 4. Console.ForegroundColor = currentForeColor; Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms"); Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0")); // 5. for (int i = 0; i <= GC.MaxGeneration; i++) { int count = GC.CollectionCount(i) - gcCounts[i]; Console.WriteLine("\tGen " + i + ": \t\t" + count); } Console.WriteLine(); } private static ulong GetCycleCount() { ulong cycleCount = 0; QueryThreadCycleTime(GetCurrentThread(), ref cycleCount); return cycleCount; } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime); [DllImport("kernel32.dll")] static extern IntPtr GetCurrentThread(); } }
时间: 2024-10-10 10:24:17