WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Creating Visual Studio Project Templates

by Ron Petrusha
10/17/2006

Often, developers perform the same repetitive operations when creating a new Visual Studio project. They frequently find themselves adding the same references and sometimes the same project items to their projects. Sometimes, developers even add more or less identical "framework" code (that is, code that performs essential operations, such as instantiating top-level objects found in an application object model). When these repetitive operations involve adding references or otherwise empty project items, they are just mildly annoying and inefficient. When they require adding repetitive code, they often become irritating and, depending on how the repetitive code is generated, error-prone as well. However, Visual Studio 2005 offers a solution to the inefficiencies of creating largely identical projects: custom project and item templates, supplemented by wizards, can automate the process of project creation and eliminate the need for developers to add the same references, the same project items, or even largely identical code to new projects.

Note: This article applies to Visual Studio project templates and wizards for Visual Studio 2005 only. In particular, it introduces a new object model for wizard development that is completely incompatible with previous versions of Visual Studio .NET.

Inside Visual Studio Project Templates

The starting point for creating a Visual Studio project is to select the type of project to be created from the New Project dialog, as shown in Figure 1. Each project that the user can create is represented by a Visual Studio template, which in turn corresponds to a Zip file stored in a predetermined location. Visual Studio recognizes two different kinds of templates:

Figure 1
Figure 1: The Visual Studio New Project dialog.

  • Standard templates, which are installed along with Visual Studio. The root directory of standard project templates is defined by the ProjectTemplatesLocation property defined in the Visual Studio settings (.vssettings) file, while the root directory of standard item templates is defined by the ProjectItemTemplatesLocation property in the Visual Studio settings file.
  • User templates, which are custom templates. The root directory of custom project templates is defined by the UserProjectTemplatesLocation value in the HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0 registry key, while the root directory of custom item templates is defined by the UserItemTemplatesLocation value in the same key.

If we open the Zip file that defines a particular Visual Studio project template, we see that it includes a number of files that will eventually be added to a newly created project. For example, in Figure 2, WinZip is displaying the files contained within the Visual Basic Console Application project template, ConsoleApplication.zip. Of the 10 files contained in the Zip file, each corresponds to a file included in a new console mode application and accessible from the Visual Studio Solution Explorer, with just two exceptions:

  • consoleapplication.vbproj, the Visual Basic project file. Although it is not displayed in Solution Explorer, it is a standard .NET project file whose values are reflected on the Application tab of the project's Properties dialog.
  • consoleapplication.vstemplate, a Visual Studio template file.

Thumbnail, click for full-size image.
Figure 2: The files contained in the ConsoleApplication.zip project template file. (Click for full-size image.)

Since it is the template file that distinguishes this collection of files as a Visual Studio project template, it is instructive to examine its contents. As Figure 3 shows, consoleapplication.vstemplate turns out to an XML file that consists of two sections, TemplateData (which provides information about how the template is to be handled) and TemplateContent (which defines the individual items to be included in the project).

Thumbnail, click for full-size image.
Figure 3: The contents of a .vstemplate file. (Click for full-size image.)

In the TemplateData section, the ProjectType tag defines the project language. The DefaultName and ProvideDefaultName tags determine whether Visual Studio provides a root project name (such as ConsoleApplication followed by a number), which it increments depending on the number of projects found in a particular solution directory to form a unique project name.

In the TemplateContent section, each ProjectItem tag defines a file to be included in a new project. The TargetFileName attribute determines the location of the project item if it is not placed in the project directory. Most interesting is the ReplaceParameters attribute, which suggests that the project item files stored in the template have replaceable parameters. In the Console Application template, only some items, including Module1.vb, AssemblyInfo.vb, and the three Designer files, have replaceable parameters. We can get some sense of what these replaceable parameters are by looking at the files whose ProjectItem tag has a ReplaceParameters attribute set to true. For example, Figure 4 shows Module1.vb, the file used to store developer code in a console application. Its replaceable parameter, $safeitemname$, is easy to pick out, since it is delimited by dollar signs. Table 1 contains a complete list of replaceable parameters used in the Visual Basic console application project template, including those found in the consoleapplication.vbproj file.

Figure 4
Figure 4: A project item with a replaceable parameter.

File Replaceable Parameter
Module1.vb $safeitemname$
AssemblyInfo.vb $projectname$
AssemblyInfo.vb $registeredorganization$
AssemblyInfo.vb $year$
AssemblyInfo.vb $guid1$
MyApplication.Designer.vb $clrversion$
Resources.Designer.vb $clrversion$
Resources.Designer.vb $safeprojectname$
Settings.Designer.vb $clrversion$
Settings.Designer.vb $safeprojectname$
consoleapplication.vbproj $safeprojectname$

Table 1: A list of replaceable parameters in the Visual Basic console mode application template.

To get a better sense of how the contents of the Visual Studio project template relate to a new project, it's also worthwhile to take a look at the project file stored in a template. Example 1 shows it in full. In addition to defining build and debug settings and determining the path of the output assembly, the project file is also responsible for defining the following:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>
    </ProductVersion>
    <SchemaVersion>
    </SchemaVersion>
    <ProjectGuid>{00000000-0000-0000-0000-000000000000}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <StartupObject>$safeprojectname$.Module1</StartupObject>
    <RootNamespace>$safeprojectname$</RootNamespace>
    <AssemblyName>$safeprojectname$</AssemblyName>
    <MyType>Console</MyType>
  </PropertyGroup>
    
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <DefineDebug>true</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <OutputPath>bin\Debug\</OutputPath>
    <DocumentationFile>$safeprojectname$.xml</DocumentationFile>
    <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  </PropertyGroup>
    
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <DefineDebug>false</DefineDebug>
    <DefineTrace>true</DefineTrace>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DocumentationFile>$safeprojectname$.xml</DocumentationFile>
    <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  </PropertyGroup>
    
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Xml" />
  </ItemGroup>

    
  <ItemGroup>
    <Import Include="Microsoft.VisualBasic" />
    <Import Include="System" />
    <Import Include="System.Collections" />
    <Import Include="System.Collections.Generic" />
    <Import Include="System.Data" />
    <Import Include="System.Diagnostics" />
  </ItemGroup>
    
  <ItemGroup>
    <Compile Include="Module1.vb"/>
    <Compile Include="My Project\AssemblyInfo.vb"/>
    <Compile Include="My Project\Application.Designer.vb">
      <AutoGen>True</AutoGen>
      <DependentUpon>Application.myapp</DependentUpon>
    </Compile>
    <Compile Include="My Project\Resources.Designer.vb">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="My Project\Settings.Designer.vb">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
  </ItemGroup>
    
  <ItemGroup>
    <EmbeddedResource Include="My Project\Resources.resx">
      <Generator>VbMyResourcesResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.vb</LastGenOutput>
      <CustomToolNamespace>My.Resources</CustomToolNamespace>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
    
  <ItemGroup>
    <None Include="My Project\Application.myapp">
      <Generator>MyApplicationCodeGenerator</Generator>
      <LastGenOutput>Application.Designer.vb</LastGenOutput>
    </None>
    <None Include="My Project\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <CustomToolNamespace>My</CustomToolNamespace>
      <LastGenOutput>Settings.Designer.vb</LastGenOutput>
    </None>
  </ItemGroup>
    
  <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
    
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->

 </Project>

Example 1: The project file in the Visual Basic console application template

  • The references automatically added to a project when it is created.
  • The namespaces that are automatically imported by the compiler. They are available on a project-wide basis without your having to use the Visual Basic Imports statement or the C# using statement.
  • The files to be included in the compilation. Note that "child" files, such as designers that are dependent on "parent" files, are marked with a DependentUpon tag.
  • Any resources to be included in the compilation.

A Visual Studio project template along with its project file allows you to define the source code files (which of course can contain custom code) to be included in a project, replace parameter strings with their values, define the assemblies references by the project, and indicate which namespaces the compiler imports on a project-wide basis.

Pages: 1, 2

Next Pagearrow