oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Creating Visual Studio Project Templates
Pages: 1, 2

Modifying or Creating a Visual Studio Project Template

One of two approaches can be used to modify a Visual Studio project template:

  • You can extract the files from an existing template that it similar to the template you'd like to create, make whatever modifications you'd like (either using a text editor or by accessing the files as an existing project from the Visual Studio environment), and store the new files either in the same Zip file or a new Zip file.
  • You can create a new project, make whatever modifications you'd like, and use the Export Template option on the Visual Studio File menu to walk you through the process of generating the template.

Although the second is the easier option, it suffers from a major limitation: If you create the project that you plan to export from a template, all replaceable string parameters will be replaced by their values, and the value of your template will be substantially reduced. This makes the first alternative the most attractive. However, you can combine these approaches without losing a project template's replaceable string parameters. To do this, follow these steps:

  1. Create a directory in which to store your project. If you store multiple projects in a single solutions directory, also create a solutions directory as the parent of the project directory.
  2. Locate the Zip file containing the Visual Studio template that most closely resembles the template you plan to create.
  3. Extract the contents of the Zip file to the project directory you've just created. If the Zip file does not do it for you, you should create the directory structure that would be created if you created the project from a template in Visual Studio. For example, in Visual C#, the AssemblyInfo.cs file is placed in the Properties subdirectory of the project directory; in Visual Basic, AssemblyInfo.vb is placed in the My Project subdirectory of the project directory.
  4. Delete the template (*.vstemplate) file.
  5. Review the files listed in the project (*.vbproj or *.csproj) file. All of the files listed must be present for Visual Studio to successfully generate a template. Modify the contents of the project file accordingly. This is also a good opportunity to rename files. The project file itself is a particularly good candidate for renaming.
  6. In Visual Studio, select the Open Project option from the File menu, and navigate to the project file that you'd like to open.
  7. Make whatever changes you desire to create the new template.
  8. Use the Export Template option from the File menu to generate the new template.
  9. Since this approach does not create a new project from an existing template, it preserves replaceable parameter strings in the project's files. This does, however, have one disadvantage: because the Visual Basic and C# compilers will not recognize the parameter strings as valid language elements, the project cannot be compiled. Instead, you'll have to use your template to create a project, which you can then compile and debug.

Visual Studio and the Templates Cache

Once a Visual Studio project session starts, it stores its templates in a cache. This means that any changes you make to a template will not be reflected until Visual Studio is closed and restarted. This is an important detail to keep in mind: you can waste hours making changes to a template, only to find that they do not appear to be reflected in new project or project items generated from that template.

Some Template Customizations

You can use this technique to generate templates that you've customized by adding new references, importing new namespaces, and using replaceable string parameters. In this section, we'll examine how to perform these three kinds of customizations before generating a new Visual Studio project template.

Adding References

To generate a template that includes additional references to .NET assemblies, right click on the Visual Basic or C# project in the Solution Explorer and select the Add Reference option from the context menu. (In Visual Basic, you can also open the project's Properties dialog and navigate to its References pane.) You can then select the references that you'd like to add to the project.

When you save your project and then export it as a template, the references you've added are present in any projects are created from that template. Both Visual Basic and C# projects behave identically in this regard.

Importing Namespaces in Visual Basic

Another of the repetitive operations that developers have to perform in each project is importing the namespaces whose types will be referenced by the project's code. Most commonly, developers find themselves importing the same namespaces into their projects, usually by adding an Imports statement (in Visual Basic) or the using statement (in C#) to the beginning of each source code file. (The statement applies only to the source code file in which it is placed, rather than to a project as a whole.)

Visual Basic provides direct support for importing namespaces into a project, rather than importing them on a file by file basis. To import a namespace for the project as a whole, open the project's Properties dialog and select the References tab. The Imported Namespaces list box, which is shown in Figure 5, allows you to see which namespaces are globally imported for your project, as well as to import additional namespaces found in the assemblies references by your project.

Figure 5
Figure 5: The Imported Namespaces list box

Project-wide imports are reflected in Import tags in the projects .vbproj file. For example, the namespaces imported in Figure 5 result in the following entries in the project's .vbproj file:

   <Import Include="Microsoft.VisualBasic" />
   <Import Include="System" />
   <Import Include="System.Collections" />
   <Import Include="System.Collections.Generic" />
   <Import Include="System.Data" />
   <Import Include="System.Diagnostics" />

Unlike Visual Basic, C# does not recognize the Import tag, and therefore does not allow you to import namespaces on a project-wide basis. However, you can modify the individual source code (.cs) files in your template to reflect the namespaces that you most commonly import.

Using Replaceable String Parameters

In addition to adding references to .NET assemblies and to importing namespaces, you can also add replaceable string parameters within project templates. Visual Studio automatically recognizes the following replaceable parameters:

Parameter Name Description
$guid1$ The GUID that identifies the project if it is exposed to COM.
$guid2$ A second project-defined GUID.
$guid3$ A third project-defined GUID.
$guid4$ A fourth project -defined GUID.
$guid5$ A fifth project -defined GUID.
$guid6$ A sixth project -defined GUID.
$guid7$ A seventh project -defined GUID.
$guid8$ An eighth project -defined GUID.
$guid9$ A ninth project -defined GUID.
$guid10$ A tenth project -defined GUID.
$time$ The current time.
$year$ The current year.
$username$ The name of the authorized user who is creating the project.
$userdomain$ The domain of the authorized user who is creating the project.
$machinename$ The name of the computer on which the project is crated.
$clrversion$ The version of the .NET runtime under which the project will run.
$registeredorganization$ The organization for which the project is being created.
$runsilent$ A flag indicating whether the template should display any user interface elements.
$projectname$ The name of the project. This is the name that the user has entered into the Name textbox when creating the project.
$safeprojectname$ The name of the project with any unsafe characters removed.
$installpath$ The path to the directory containing the project template used to generate the project.
$exclusiveproject$ Determines whether the current solution is closed and a new one opened before the new project is created. If True, the solution is closed; if False, the new project is added to an existing solution.
$destinationdirectory$ The path to the project directory.

Table 2.

For example, you may find that, when creating console mode projects, you always change the name of the class or module in your source code to match that of your project. By making the following simple modification to the Console Application template, you can have Visual Studio make this change for you when it generates the project's files:

' Modification to Module1.vb in Visual Basic projects
Module $safeprojectname$

// Modification to Program.cs in C# projects
   class $safeprojectname$

In addition to making use of existing replaceable strings in your custom templates, you can also add your own custom replaceable strings. These are defined by the <CustomParameters> node in the Visual Studio template (.vstemplate) file and take the following form:

   <CustomParameter Name="$name$" Value="value" />

To add custom replaceable string parameters to a project, you first have to generate the Visual Studio project or item template, extract and edit its .vstemplate file. The <CustomParameters> node should be inserted just before the closing </TemplateContent> tag. Then replace the old version of .vstemplate file in the template Zip file with the new one.

Custom string parameters are most useful when a Visual Studio project or item template is linked with a wizard. Even without custom templates, however, they can be useful. For example, a single project template might be used to target different versions of a particular object model. To take a very simple example, version 1.0 of a small object model is contained in a class named CompanySDK1 in an assembly of the same name. Version 2.0 of the object model is contained in a class named CompanySDK2, also in an assembly of the same name. CompanySDK1 includes a DisplaySDKVersion method, which is inherited by CompanySDK2, that displays the version of the SDK used by the application. A single template can be developed to handle both versions. For example, the code contained in a template that instantiates the versioned application object and calls its DisplaySDKVersion method might appear as follows:

Imports CompanySDK

Module Module1]
   Sub Main()
      Dim versionedSDK As New $versionedClass$
      versionedSDK.DisplaySDKVersion ()
   End Sub
End Module

Two templates that differ only in their single custom parameter can then be generated from this project. The template supporting version 1.0 of the SDK has the following <CustomParameters> node:

   <CustomParameter Name="$versionedClass$" Value="CompanySDK1" />

The template supporting version 2.0 of the SDK has the following <CustomParameters> node:

   <CustomParameter Name="$versionedClass$" Value="CompanySDK2" />

Ron Petrusha is the author and coauthor of many books, including "VBScript in a Nutshell."

Return to the Windows DevCenter.