are creating new items. Two subfolders beneath the Templates folder
hold item templates and project templates, respectively. These in
turn are divided further by language. If you check the Automatically
Import the Template into Visual Studio option on the final page of
the Export Template Wizard, the new template will not only be placed
in the output folder but will also be copied to the relevant location
(depending on language and template type) within the Templates
folder. Visual Studio 2010 will automatically display this item
template the next time you display the Add New Item dialog, as
shown in Figure 15-6.
fiGure 15-5
Creating Templates .
295
fiGure 15-6
If you want an item or project template to appear under an existing category (or
one of your own) in the Add New Item / New Project dialog (such as the Windows
Forms category), simply create a folder with that name and put the template into it
(under the relevant location as described for that template). The next time you open
the Add New Item / New Project dialog, the template will appear in the category
with the corresponding folder name (or as a new category if a category matching
the folder name doesn’t exist).
Project template
You build a project template the same way you build an item
template, but with one difference. Whereas the item template is based
on an existing item, the project template needs to be based on an
entire project. For example, you might have a simple project called
ProjectTemplateExample (as shown in Figure 15-7) that has a main
form, an About form, and a splash screen.
fiGure 15-7
To generate a template from this project, you follow the same steps you
took to generate an item template, except that you need to select Project Template when asked what
type of template to generate, and there is no step to select the items to be included (all items within
the project will be included in the template). After you’ve completed the Export Template Wizard, the
new project template will appear in the New Project dialog, shown in Figure 15-8.
296 .
chaPter 15 projecT And iTem TemplATeS
fiGure 15-8
template structure
Before examining how to build more complex templates, you need to understand what is produced
by the Export Template Wizard. If you look in the My Exported Templates folder, you will see that
all the templates are exported as a single compressed zip file. The zip file can contain any number of
files or folders, depending on whether they are templates for single files or full projects. However,
the one common element of all template zip files is that they contain a .vstemplate file. This file is
an XML document that holds the template configuration. The following listing is the .vstemplate
file that was exported as a part of your project template earlier:
<VSTemplate Version="2.0.0"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
<TemplateData>
<Name>Project Template Example</Name>
<Description>Project Template Example</Description>
<ProjectType>CSharp</ProjectType>
<ProjectSubType>
</ProjectSubType>
<SortOrder>1000</SortOrder>
<CreateNewFolder>true</CreateNewFolder>
<DefaultName>Project Template Example</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<Project TargetFileName="ProjectTemplateExample.csproj"
File="ProjectTemplateExample.csproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.cs">
AboutForm.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.Designer.cs">
AboutForm.Designer.cs</ProjectItem>
Creating Templates .
297
< ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.resx" >
AboutForm.resx < /ProjectItem >
< ProjectItem ReplaceParameters="true" TargetFileName="MainForm.cs" >
MainForm.cs < /ProjectItem >
< ProjectItem ReplaceParameters="true" TargetFileName="MainForm.Designer.cs" >
MainForm.Designer.cs < /ProjectItem >
< ProjectItem ReplaceParameters="true" ="Program.cs" > Program.cs < /ProjectItem >
< Folder Name="Properties" TargetFolderName="Properties" >
< ProjectItem ReplaceParameters="true"
TargetFileName="AssemblyInfo.cs" > AssemblyInfo.cs < /ProjectItem >
< ProjectItem ReplaceParameters="true"
TargetFileName="Resources.resx" > Resources.resx < /ProjectItem >
< ProjectItem ReplaceParameters="true"
TargetFileName="Resources.Designer.cs" > Resources.Designer.cs
< /ProjectItem >
< ProjectItem ReplaceParameters="true"
TargetFileName="Settings.settings" > Settings.settings < /ProjectItem >
< ProjectItem ReplaceParameters="true"
TargetFileName="Settings.Designer.cs" > Settings.Designer.cs < /ProjectItem >
< /Folder >
< ProjectItem ReplaceParameters="true" TargetFileName="SplashForm.cs" >
SplashForm.cs < /ProjectItem >
< ProjectItem ReplaceParameters="true"
TargetFileName="SplashForm.Designer.cs" >
SplashForm.Designer.cs < /ProjectItem >
< ProjectItem ReplaceParameters="true" TargetFileName="SplashForm.resx" >
SplashForm.resx < /ProjectItem >
< /Project >
< /TemplateContent >
At the top of the file, the VSTemplate node contains a Type attribute that specifies whether this is an
item template (Item), a project template (Project), or a multiple project template (ProjectGroup).
The remainder of the file is divided into TemplateData and TemplateContent. The TemplateData
block includes information about the template itself, such as its name and description and the icon
that will be used to represent it in the New Project dialog, whereas the TemplateContent block
defines the file structure of the template.
In the preceding example, the content starts with a Project node, which indicates the project file
to use. The files contained in this template are listed by means of the ProjectItem nodes. Each
node contains a TargetFileName attribute that can be used to specify the name of the file as it will
appear in the project created from this template. In the case of an item template, the Project node
is missing and ProjectItems are contained within the TemplateContent node.
It’s possible to create templates for a solution that contains multiple projects.
These templates contain a separate .vstemplate file for each project in the
solution. They also have a global .vstemplate file, which describes the overall
template and contains references to each projects’ individual .vstemplate
files. Creating this file is a manual process, however, as Visual Studio does not
currently have a function to export a solution template.
298 . Chapter 15 Project and It em Templat es
For more information on the structure of the .vstemplate file, see the full schema at
%programfiles%\Microsoft Visual Studio 10.0\Xml\Schemas\1033\vstemplate.xsd.
Template Parameters
Both item and project templates support parameter substitution, which enables replacement
of key parameters when a project or item is created from the template. In some cases these are
automatically inserted. For example, when the About form was exported as an item template, the
class name was removed and replaced with a template parameter, as shown here:
Public Class $safeitemname$
Table 15-1 lists 14 reserved template parameters that can be used in any project.
Table 15-1: Template Parameters
Parameter Description
clrversion Current version of the common language runtime.
GUID[1-10] A GUID used to replace the project GUID in a project file.
You can specify up to ten unique GUIDs (for example, GUID1,
GUID2, and so on).
itemname The name provided by the user in the Add New Item dialog.
machinename The current computer name (for example, computer01).
projectname The name provided by the user in the New Project dialog.
registeredorganization The registry key value that stores the registered organization
name.
rootnamespace The root namespace of the current project. This parameter is
used to replace the namespace in an item being added to a
project.
safeitemname The name provided by the user in the Add New Item dialog,
with all unsafe characters and spaces removed.
safeprojectname The name provided by the user in the New Project dialog,
with all unsafe characters and spaces removed.
time The current time on the local computer.
userdomain The current user domain.
username The current username.
webnamespace The name of the current web site. This is used in any web
form template to guarantee unique class names.
year The current year in the format YYYY.
extending Templates .
299
In addition to the reserved parameters, you can also create your own custom template parameters.
You define these by adding a <CustomParameters> section to the .vstemplate file, as shown here:
<TemplateContent>
...
<CustomParameters>
<CustomParameter Name="$timezoneName $" Value="(GMT+8:00) Perth"/>
<CustomParameter Name="$timezoneOffset $" Value="+8"/>
</CustomParameters>
</TemplateContent>
You can refer to this custom parameter in code as follows:
string tzName = "$timezoneName$";
string tzOffset = "$timezoneOffset$";
When a new item or project containing a custom parameter is created from a template, Visual
Studio automatically performs the template substitution on both custom and reserved parameters.
template locations
By default, custom item and project templates are stored in the user’s personal Documents\Visual
Studio 2010\Templates folder, but you can redirect this to another location (such as a shared
directory on a network so you are using the same custom templates as your colleagues) via the
Options dialog. Go to Tools . Options and select the Projects and Solutions node. You can then
select a different location for the custom templates here.
extendinG teMPlates
Building templates based on existing items and projects limits what you can do. It assumes that
every project or scenario will require exactly the same items. Instead of creating multiple templates
for each different scenario (for example, one that has a main form with a black background and
another that has a main form with a white background), with a bit of user interaction you can
accommodate multiple scenarios from a single template. Therefore, this section takes the project
template created earlier and tweaks it so users can specify the background color for the main form.
In addition, you’ll build an installer for both the template and the wizard that you will create for
the user interaction.
To add user interaction to a template, you need to implement the IWizard interface in a class library
that is then signed and placed in the Global Assembly Cache (GAC) on the machine on which the
template will be executed. For this reason, to deploy a template that uses a wizard you also need
rights to deploy the wizard assembly to the GAC.
template Project setup
Before plunging in and implementing the IWizard interface, follow these steps to set up your
solution so you have all the bits and pieces in the same location, which will make it easy to make
changes, perform a build, and then run the installer:
1 .
Create a new project with the Project Template Example project template that you created
earlier in the chapter and name it ExtendedProjectTemplateExample. Make sure that this
300 .
chaPter 15 projecT And iTem TemplATeS
solution builds and runs successfully before proceeding. Any issues with this solution will
be harder to detect later, because the error messages that appear when a template is used are
somewhat cryptic.
2 Into this solution add a Class Library project, called WizardClassLibrary, in which you will
place the IWizard implementation.
3 Add to the WizardClassLibrary a new empty class file called MyWizard, and a blank
Windows Form called ColorPickerForm. These will be customized later.
4 To access the IWizard interface, add to the Class Library project EnvDTE.dll and
Microsoft.VisualStudio.TemplateWizardInterface.dll as references, both located at
%programfiles%\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\.
5 Finally, you will also need to add a Setup project to
the solution. To do this, select File . Add . New
Project, expand the Other Project Types category,
and then highlight Setup and Deployment. Select the
Setup Wizard template and follow the prompts to
include both the Primary Output and Content Files
from WizardClassLibrary.
This should result in a solution that looks similar to what is
shown in Figure 15-9.
As shown in Figure 15-9, when you include the primary
output and content files from the Class Library project to the
installer it also adds a number of dependencies. Because
the template will only be used on a machine with Visual
Studio 2010, you don’t need any of these dependencies.
Exclude them by clicking the Exclude menu item on the right-
click context menu. Then perform the following steps to
complete the configuration of the Installer project:
1 .
When you add primary outputs and content files from projects in the solution to the