在开始另一本技术书籍或探索一个新的框架或平台之后,这会浪费很多时间,而烦人的事情就是样板和不必要的设置。 良好而快速地启动项目可以帮助您专注于学习和使用自己的代码的重要部分。
因为我使用的某些东西都是基于C ++的,所以Visual Studio是一个很棒的平台,提供了很多可扩展性选项。 在VS中创建项目模板的基本操作是使用“导出模板”功能对所有项目进行设置后。
这将创建一个新的zip文件,其中包含将项目模板添加到安装中的所有VS需求。 创建的最重要的文件是MyTemplate.vstemplate,它包含有关包含哪些文件的所有信息,应进行哪些字符串替换以及VS如何设置使用此模板创建的项目。 可以轻松地使用此操作来节省制作复杂模板的时间。
创建一个更复杂的项目,或者创建一个不是从基本项目类型派生的项目,或者需要一个更复杂的模板中的数据生成的项目,我们必须制作一个VSIX扩展项目。
在开始之前,我们需要安装Visual Studio SDK,与旧版本相比,此操作更容易完成,因为它是功能安装程序的一部分。 从工具→获取工具和功能,以便我们可以创建VSIX项目。
首先,我们将需要一个VSIX项目来将内容整理得井井有条,它创建了一个易于分发甚至可以添加到市场的文件。
创建C#项目模板
这将是我们包含所有模板文件的占位符项目。 为了使事情更易于管理和结构化,我们将使用这个项目来包含我们所有的模板文件和支持代码。 在拥有项目之后,我们将其添加为VSIX项目中的ProjectTemplate资产(通过source.extension.vsixmanifest完成)。
如果您的模板是如此简单,以至于它们不需要其他任何东西,您可以只使用一个VSIX项目,将其自身添加为ProjectTemplate资产,并将所有导出的zip文件和模板放置在项目根目录中名为ProjectTemplates的文件夹中。
设置.vstemplate文件
Visual Studio项目模板的本质是描述模板的元数据,行为和内容的xml文件。
.vstemplate文件的基本结构如下所示:
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
<TemplateData>
<Name>OpenMP Project</Name>
<Description>A starter template for OpenMP project research</Description>
<ProjectType>VC</ProjectType>
<ProjectSubType>
</ProjectSubType>
<SortOrder>1000</SortOrder>
<CreateNewFolder>true</CreateNewFolder>
<DefaultName>OpenMP Project</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
<Icon>openmp_icon.png</Icon>
<Hidden>false</Hidden>
</TemplateData>
<TemplateContent>
<Project TargetFileName="$projectname$.vcxproj" File="OpenMPTemplate\OpenMPTemplate.vcxproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="false" TargetFileName="$projectname$.vcxproj.filters">OpenMPTemplate\OpenMPTemplate.vcxproj.filters</ProjectItem>
<ProjectItem ReplaceParameters="false" TargetFileName="main.cpp">OpenMPTemplate\main.cpp</ProjectItem>
</Project>
</TemplateContent>
</VSTemplate>
仅具有这两个元素<TemplateData>,<TemplateContent>和VSTemplate根元素的属性Type =“ Project”的简单结构。 模板数据描述了它是什么类型的项目以及Visual Studio必须如何处理它。
我们可以创建的另一种模板是组模板,该组模板实际上创建了一个由多个链接到该组的.vstemplate文件组成的解决方案。 我们可以添加的另一个有用的东西是向导(将在下一章中进行介绍),该向导使您与项目创建更具交互性。 向导可以使您能够在创建对话框之前与对话框进行交互,从VS访问配置或自定义替换参数。
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
<TemplateData>
<Name>Parallel Project templates</Name>
<Description>An example of a multi-project template</Description>
<ProjectType>VC</ProjectType>
<Hidden>false</Hidden>
</TemplateData>
<TemplateContent>
<ProjectCollection>
<ProjectTemplateLink ProjectName="OpenMPTemplate">
OpenMPTemplate\OpenMPTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="OpenCLTemplate">
OpenCLTemplate\OpenCLTemplate.vstemplate
</ProjectTemplateLink>
</ProjectCollection>
</TemplateContent>
</VSTemplate>
这是一个示例组项目模板,您可以看到它是一个普通项目模板,我们在<ProjectCollection>中添加了Type =“ ProjectGroup”和<ProjectTemplateLink>元素。 这些元素仅链接到描述组中项目的真实模板。 您也可以使用<SolutionFolder>定制解决方案的存储方式。
模板文件结构
简单地说,您要添加的每个项目模板都是一个包含所有文件和.vstemplate文件的文件夹,就像“导出模板”过程在zip文件中生成文件的方式一样。应该将使用组模板添加到根目录,以便可以轻松引用所有项目模板文件夹。
创建项目模板向导
将向导附加到项目模板可让您控制模板内容的生成方式。例如,您可以有一个对话框,其中包含几个选项,并且基于用户选择跳过创建某些文件或替换为其他参数的选择。
所有这些操作都非常简单,例如制作带有某些表单的应用程序并将其配置为程序包中的项目模板。
我们可以将一个类添加到保存模板的现有项目中,或者为该向导创建一个新项目。根据您的操作,稍后应参考相应的程序集(进一步说明)。
之后,我们需要创建实现IWizard接口的Wizard类。您还应该将以下引用添加到项目System.Windows Forms,EnvDTE和Microsoft.VisualStudio.TemplateWizardInterface
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TemplateWizard;
using System.Windows.Forms;
using EnvDTE;
namespace Root_Template_Placeholder
{
class OpenCLProjectWizard : IWizard
{
private UserInputForm inputForm;
private string customMessage;
public void BeforeOpeningFile(ProjectItem projectItem)
{
}
public void ProjectFinishedGenerating(Project project)
{
}
public void ProjectItemFinishedGenerating(ProjectItem projectItem)
{
}
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());
}
}
public bool ShouldAddProjectItem(string filePath)
{
return true;
}
}
}
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();
}
}
这个简单的实现使用WinForms创建一个对话框窗口,我们在其中输入自定义消息作为替换参数。 这是通过将我们从对话框中获得的输入添加到模板的replaceDictionary中来实现的。
也可以使用WPF代替WinForms进行对话框,因此我将链接一个示例(WPF示例代码)
为了使向导与模板相关联,我们必须在VSIX程序包中包含一个需要签名的程序集,因为我们需要为其指定一个完全限定的名称。
签署程序集的快速步骤(确保您以管理员身份运行VS):
1.在Assembly项目(一个创建程序集的项目)上,转到Properties→Signing。 添加一个新的登录密钥(如下所示),无需密码保护。
2.构建解决方案后,您会看到生成了一个key.snk文件,为方便起见,您可以选择将文件复制到构建输出目录。 打开命令提示符,然后转到包含我们要签名的程序集的输出目录。
在系统上找到sn.exe,
Find sn.exe on your system, its usually located in a path like this “C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools\sn.exe” (when you have a path with spaces dont forget to add quotes to run the executable )
3.运行以下命令(如果路径包含空格,请不要忘记引用路径)
“<sign_tool_path>\sn.exe” -p key.snk outfile.key
“<sign_tool_path>\sn.exe” -t outfile.key
如果一切顺利,您应该得到类似“公钥令牌是<token>”的输出。 记下该值。
现在,我们将另一个标签添加到.vstemplate中以进行提取,向导称为<WizardExtension>
<WizardExtension>
<Assembly>RootTemplatePlaceholder, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=9a0a174492e9b787</Assembly>
<FullClassName>RootTemplatePlaceholder.TBBProjectWizard</FullClassName>
</WizardExtension>
在这里,您只需设置适当的程序集版本和我们从key.snk生成的PublicKeyToken
向导的主要功能是RunStarted方法
在项目创建对话框中单击“创建”后,将执行RunStarted方法,这是进行某些更改或请求用户输入的绝佳机会。
在模板中设置参数
这基本上是项目模板文件中的字符串替换,该项目模板文件中.vstemplate中的ReplaceParameters属性设置为true,因此我们还可以选择从替换中排除文件。有两种指定参数的方式:
使用.vstemplate <CustomParameter>
在向导中使用RunStared方法修改replaceDictionary
使用<CustomParameter>:
在模板内容元素内放置一个<CustomParameters>标记,它充当所有自定义参数的容器。每个参数都有一个名称和一个值。这意味着名称内容的每个实例都将替换为相应的值。为了与模板文件中的其他文本区分开来,使用名称开头和结尾带有美元符号的表示法。
<CustomParameters>
<CustomParameter Name="$color1$" Value="Red"/>
<CustomParameter Name="$color2$" Value="Blue "/>
</CustomParameters>
另外,为方便起见,可以在此处找到一些用于基本项目创建和命名的保留项。
摘要
- 创建您的项目结构
- 导出模板
- 创建VSIX和占位符项目
- 将模板添加到占位符项目
- 编辑替换和向导
- 发布/使用
结论
最后,请尝试使自己的模板变得有趣,因为从长远来看,您投入的所有工作都会有所回报。 也许您想创建样板项目模板,以帮助您测试和试验语言功能或某些框架:),还学习如何做所有这些工作,我创建了自己的项目模板,用于为OpenCL的线程构建块创建基础项目(使用 您可以在此处找到Nvidia SDK)和OpenMP。