Creating VSTemplates


Probably the most common type of content that you will be sharing with others is templates. In earlier versions of Visual Studio, if you wanted to create a project or project item that the user could add to the New Project or Add New Item dialog boxes for cloning, you had to write a wizard. Writing a wizard to generate even a simple project was not easy, so to make this process easier, Visual Studio 2005 offers a new wizard technology that makes creating reusable projects and project items easier than ever. This technology, VSTemplates, enables you to quickly create a new project or project item to import into a solution or project by putting together an XML file that describes the files that make up your project or project item. When the user runs your template through the New Project or Add New Item dialog boxes, Visual Studio will start the template wizard, which then reads and processes the XML file, creating the project or project item for you. The VSTemplate wizard turns generating projects and project items into a data-driven process. Each item that appears in the New Project and Add New Item dialog boxes, when added to a solution or an existing project, uses the VSTemplate wizard to generate the project and project items. And of course, you can create your own template files to appear within these dialog boxes.

Using the Export Template Wizard

The easiest way to get started creating a VSTemplate is to use the Export Template Wizard. This wizard will examine a project or project item that is loaded into a solution or project, and it will generate a VSTemplate that you can use within the Add New Item or New Project dialog boxes to create new project items or projects. You can also package these files into a .vsi file for easy distribution to other users. This wizard is available from the File menu, and it will quickly generate a .zip file containing a .vstemplate file and the files necessary to recreate an item within a project or a project and its contents.

To use the wizard, you must first have one or more Visual Basic, Visual C#, Visual J#, or Web projects opened in a solution. After you start the wizard, you will see a dialog box like that shown in Figure 4-7.

image from book
Figure 4-7: The first step of the Export Template Wizard

This dialog box gives you two different options. The first, Project Template, will generate a template for a project. The Item Template option, if selected, will enable you to export one single file from within a project. After you choose to export either a project or project item, you then select which project to export, or the project containing the item to export. This is done from within the first drop-down box, which gives a list of all projects that are within the currently open solution. The final drop-down box on this page is only visible when you have selected a Web project to export and allows you to select the programming language for the Web project.

If you select to export a project item and then click the Next button, the dialog box shown in Figure 4-8 will appear.

image from book
Figure 4-8: Selecting a project item to export

Here, you can navigate through the tree to find an item to turn into a template. If you were to select one item and then select another, the check box on the first item will be cleared. Some items, such as forms or controls, can contain multiple items. For example, a Windows form could have a Form1.cs file, a Form1.designer.cs file, and a Form1.resx file. The dependent items (Form1.designer.cs and Form1.resx) will not appear in this step of the wizard, but if you select the Form1.cs file, even though you do not see those items in the tree, they will automatically be exported. When you click the Next button, a list of assemblies referenced by the project in which the item is located is given. (See Figure 4-9.) When the template is added to a project, any references that you select in this step of the wizard will also be added to the project. Suppose you are adding a Windows Form to a console application. If you were to select the check box next to the System.Windows.Forms assembly, the user importing your form will not need to manually add the reference to System.Windows.Forms because the template wizard will take care of adding that reference for you.

image from book
Figure 4-9: Selecting the references to import when the project item is added to a project

The final page of exporting a project item is the same as the final step of exporting a project. (See Figure 4-10.) This step in the wizard allows you to select an icon to use within the New Project or Add New Item dialog boxes. It also allows you to specify the text to show beneath the icon by changing the Template name field. The description of the template shown within the New Project and Add New Item dialog boxes can be changed by modifying the Template description field.

image from book
Figure 4-10: The final page of the Export Template Wizard

After you click Finish, the wizard will gather the data that you entered, generate a .vstemplate file, package together all the files that make up your project, and then create a .zip file containing this data. If the Automatically Import The Template Into Visual Studio check box is selected, the .zip file is placed into the correct location so that if you were to open the New Project or Add New Item dialog boxes immediately after exporting the template, the template appears in the My Templates section of these dialog boxes. A copy of the template is also stored into the C:\Documents and Settings\username\My Documents\ Visual Studio 2005\My Exported Templates folder, making it easier for you to find the template and send it to others, or to package it into a .vsi file.

Creating Templates by Hand

Although the template wizard will quickly generate a project or project item template for you, there could be times when you want to customize the template beyond what the Export Template Wizard automatically generates. To create a template, you need a set of files that will produce the sources for the new project or new project item that the user will create. The template wizard supports only Visual Basic, Visual C#, Visual J#, and Web projects, so your base project must be of one of these types. After you have created your base project or project item, you then need to go through those files and insert special strings, called replacement tokens, into the source and project files. The Export Template Wizard automatically scans all the file s in the project for specific strings, such as the name of the project, and replaces those strings with a replacement token. When the template wizard processes your source files, the files are searched for the replacement tokens. When one is found, the token is replaced with a value that is dependent on the state of your computer and the files that are currently open inside of Visual Studio. For example, suppose your company used a common header at the top of each source file that looked like the following:

 //----------------------------------------------------------------- // Class1.cs // // (C) Copyright 1999 My Company. // // Contents: My source code file // // Owner: UserName // // Revisions: 02/07/2005 14:24:35 Created by UserName // //----------------------------------------------------------------- 

You could modify your template file so that when processed by the wizard, it is automatically modified to contain the relevant information. The modified template would look like this:

 //------------------------------------------------------------------ // $itemname$ // // (C) Copyright $year$ $registeredorganization$. // // Contents: My source code file // // Owner: $username$ // // Revisions: $time$ Created by $username$ // //------------------------------------------------------------------ 

There are many different replacement values available for use within your project files. Table 4-2 lists these values, as well as possible values and a description.

Table 4-2: Replacement Values

Replacement Variable

Example Value

Description

$guid1$,$guid2$,$guid3$,$guid4$,$guid5$,$guid6$,$guid7$,$guid8$,$guid9$,$guid10$

These variables are used for generating globally unique identifiers (GUIDs) within source code. They can be used when a unique value is necessary, including for generating COM object code.

$time$

02/07/2005 14:24:35

The time that the source code file was generated.

$year$

2005

The year that the source code was generated.

$username$

Craigs

The name of the user who is currently logged on to the computer.

$userdomain$

Redmond

The name of the domain, if available, that the computer is a member of. At Microsoft, the name of the domain that most users belong to is Redmond.

$machinename$

CraigsLaptop

The name of the computer on the network.

$clrversion$

v2. 0.50215

The version of the .NET Framework that is being used by Visual Studio at the time the file is processed to build the program.

$registeredorganization$

Microsoft

The name of the organization that owns the license for the operating system. This value is entered when installing the operating system when the user is prompted for the user name and organization.

$itemname$

My ClassFile

The file name as entered by the user, but with the extension removed.

$safeitemname$

My_ClassFile

The file name as entered by the user, but modified so that the name can be used as an identifier. Any character that would not be recognized as a valid identifier character is replaced with an underscore. This name does not include the extension.

$itemrootname$

My Form1.vb

This is the name of an item being added to either a new or existing project.

$safeitemrootname$

My_Form1.vb

The same as $itemrootname$, but in a form that can be used as a programmatic identifier.

$fileinputname$

Form1

Available only to Add New item templates, this is the file name entered into the Add New Item dialog box. If the name entered into the dialog box is Form1.MyForm.vb, this value will be Form1. MyForm.

$fileinputextension$

.vb

Available only to Add New Item templates, this is the extension of the file name entered into the Add New Item dialog box.

$rootnamespace$

WindowsApplication1

Available only to Add New item templates, this is the default namespace, as specified in the project properties window, for the project. If an item is added to a folder of a project, this value will also include the folder name. For example, adding a file to a folder named NewFolder will cause $rootnamespace$ to be WindowsApplication. NewFolder.

$runsilent$

true/false

This value is set to true when any user interface that the wizard may display should be hidden, and it's set to false if UI can be shown

$wizarddata$

 

Within the VSContent XML file, you can create a tag named <WizardData> under the document node. Any data within this tag is passed along through this value.

$rootname$

Form1.vb

This is the complete file name entered in the Add New Item dialog box.

$projectname$

My Project1

The name of the project.

$safeprojectname$

My_Project1

The name of the project, but modified in a way that allows you to use the name as an identifier in your source code.

$installpath$

C:\Program Files\Microsoft Visual Studio8\Common7\IDE

The directory in which Visual Studio is installed.

$exclusiveproject$

true/false

If this value is false, the project is being added to an existing project; otherwise, the project is being added to a new solution.

$destinationdirectory$

C:\Documents and Settings\craigs\My Documents\Visual Studio 2005\Projects\MyProjectName

The directory into which the new project is being created.

Note 

Not only can you create your own templates by hand, but you can also modify templates generated with the Export Template wizard. Simply export a template, open the .zip file containing the template, and then modify the files to your liking. When you are done, add the modified files to the .zip file.

The VSTemplate Schema

After you have modified your project or project item to contain the replacement tokens, you now need to create an XML file that describes to the template wizard how the project or project item should be re-created. This file, which has the extension .vstemplate, begins with a <VSTemplate> tag and has three XML attributes. The Version attribute specifies the version of the wizard that the XML file is designed to work with. For Visual Studio 2005, the version number is 2.0.0. The second attribute, Type, specifies the type of items that can be generated with the .vscontent file. Currently, three types of items are supported: Project, Item, and ProjectGroup. If you are creating a new project template, the value is Project; if you are creating a new project item, the value is Item. The template wizard also supports creating multiple projects at a time within the solution. Suppose you need to create a Web Service application and a console application that consumes that Web Service. With a template type of ProjectGroup, you could create both of these projects at once rather than create them separately. Finally, the xmlns attribute lists the XML Schema of the file. The following XML is the most basic of .vstemplate files:

 <VSTemplate Version="2.0.0" Type="Project" xmlns=   "http://schemas.microsoft.com/developer/vstemplate/2005"> </VSTemplate> 

A .vstemplate file has two main sections. The TemplateData section describes the visual representation of the template in the UI. The second section, TemplateContent, details each file that is part of your template and how those files should be re-created in the target solution or project.

The TemplateData Section

The TemplateData section is within the VSTemplate section of the .vscontent file. This section determines the appearance of templates within the New Project and Add New Item dialog boxes. An example of this section looks like this XML fragment, which defines a custom C# class library template:

 <TemplateData>   <Name>My Class Library</Name>   <Description>A project for creating a C# class library (.dll)</Description>   <Icon>AnIcon.ico</Icon>   <ProjectType>CSharp</ProjectType>   <SortOrder>20</SortOrder>   <DefaultName>ClassLibrary</DefaultName>   <ProvideDefaultName>true</ProvideDefaultName> </TemplateData> 

The tags of this XML have the following meanings:

  • Name This is the name of the item shown underneath the icon within the New Project or Add New Item dialog boxes.

  • Description This is the text shown when the user selects the icon in the New Project or Add New Item dialog boxes, giving the user more information about what type of project will be created when the template is processed.

  • Icon A path, relative to where the .vstemplate file is located, to the icon to display within the New Project or Add New Item dialog boxes.

  • ProjectType Can either be CSharp, JSharp, VisualBasic, or Web. This controls which node of the tree on the left side of the New Project dialog box the item will appear under, or, if the template is an item template, it specifies the project that the item can be added to.

  • SortOrder This is the priority of the item within the New Project or Add New Item dialog boxes. The lower this value is, the higher it will appear to the top of these dialog boxes.

  • DefaultName This is the default name of the new project or project item that appears in the New Project or Add New Item dialog boxes. Visual Studio takes this name and appends a value onto the end of the name starting at 1. If a project or project item with that name exists, the number is incremented until a unique name is found.

  • ProvideDefaultName If this is true, then the Name field of the New Project or Add New Item dialog box will contain a default value based upon the DefaultName value. Otherwise, the project name is <Enter name>, and the user must manually enter a valid project name to continue.

The TemplateContent Section

The TemplateContent section is where you specify the directory structure layout on disk for your project. When the template wizard opens your .vstemplate file, it reads this section and copies the listed file or files into a temporary location. From this temporary location, the files are added to the solution (if the .vstemplate specifies a new project or project group) or added to the project (if the .vstemplate specifies a project item). This section looks different depending on whether you are creating a project, a project item, or a group project. An example TemplateContent section for creating new projects, taken from the C# class library template, looks like this:

   <TemplateContent>     <Project File="ClassLibrary.csproj" ReplaceParameters="true">        <ProjectItem ReplaceParameters="true"         TargetFileName=          "Properties\AssemblyInfo.cs">>          AssemblyInfo.cs</ProjectItem>        <ProjectItem ReplaceParameters="true"       OpenInEditor="true">         Class1.cs</ProjectItem>     </Project>   </TemplateContent> 

Here, a project file with the name ClassLibrary.csproj is expected to be in the same folder as the .vstemplate file. This project file, along with two files, AssemblyInfo.cs and Class1.cs, are copied into the temporary folder. Class1.cs will be copied into the same folder as ClassLibrary.csproj, but for AssemblyInfo.cs, two file names are given, AssemblyInfo.cs and Properties\AssemblyInfo.cs. If only one file name is given (because the TargetFileName attribute is not supplied), the source file is read from the same folder containing the .vstemplate file, and the file is copied into the project destination folder. Because, in this example, two file names are given in the <ProjectItem>tag, a folder named Properties will be created and the AssemblyInfo.cs file will be copied into that folder This allows you to fine-tune exactly how the directory structure for a project or project items are re-created on disk. You could also give a relative path for the text of the ProjectItem tag, such as Properties\AssemblyInfo.cs. When the template wizard processes that item, the AssemblyInfo.cs file is copied from a subfolder named Properties into the folder named Properties within the temporary folder. Thus, you can write the line of XML to copy the AssemblyInfo.cs into a Properties folder using these three styles:

 <ProjectItem ReplaceParameters="true"  TargetFileName="Properties\AssenbleyInfo.cs">  AssemblyInfo.cs </ProjectItem> <ProjectItem ReplaceParameters="true">  Properties\AssemblyInfo.cs </ProjectItem> <ProjectItem ReplaceParameters="true"  TargetFileName="Properties\AssemblyInfo.cs">  Properties\AssemblyInfo.cs </ProjectItem> 

The first line requires the Assemblyinfo.cs file to be in the same folder as the .vstemplate file, whereas for the second and third possibilities, the template wizard expects the file to be in a folder named Properties. All three styles will copy the file into a folder named Properties.

Note 

It is important to distinguish a project file from the TemplateContent section of a .vscontent file for creating projects. A project file, such as a file ending in the extensions .csproj, .vbproj, or vjsproj, defines the programming language–specific layout of a project on disk and how that project is loaded into Visual Studio. A .vstemplate file is a programming language–agnostic way of defining a project or project item. It might seem unnecessary to have both a project and a template file because they both contain similar data, but a separate .vstemplate file has its purpose. A group project template and project items do not have an associated project file, so the .vstemplate file is needed in that case. In addition, because the .vstemplate file is independent of language, you can use one file format to create projects for multiple languages, even languages not created by Microsoft.

In all three files from the example .vstemplate file, the ReplaceParameters attribute is set to true, meaning that files will be opened in the temporary folder and examined for replacement parameters, and if any are found, they will be replaced. If you do not have any replacements to make in a file, you can set this value to false (or not even give the attribute—it defaults to false) and increase performance by a little bit, because if this value is false, the steps to open the file and scan for replacement tokens that will not exist can be bypassed.

This sample also makes use of the OpenInEditor attribute. If this attribute is set to true, when the wizard finishes building the project or project item, it will open all the files with this attribute. With the OpenInEditor attribute, you can also optionally use the OpenOrder attribute. This attribute takes an integer value and lets you control the order in which documents are opened. If you were to use the OpenInEditor="true" attribute on multiple files, then all the files will be opened, but only one will be the active window in the Visual Studio UI when the wizard is complete. If you use the OpenOrder attribute, the file with the highest value is opened last and will then be active in the UI.

An example <TemplateContent> section for creating new project items, which was taken from the C# class template, looks like this:

 <TemplateContent>  <References>   <Reference>    <Assembly>    System, Version=2.0.0.0, Culture=neutral,    PublicKeyToken=b77a5c561934e089    F</Assembly>   </Reference>  </References>  <ProjectItem ReplaceParameters="true">Class.cs</ProjectItem> </TemplateContent> 

A new project item template is similar to new project templates, except that a project item template does not have an associated project file, so the <Project>tag is removed and the <ProjectItem>tag becomes a child of the <TemplateContent> tag. Also, a <References>, <Reference>, and <Assembly> tag has been added to the XML. After the Class.cs file has been added to the project, the template wizard will use the XML XPath query for References/Reference/Assembly tags, and, if found, the wizard will add the assembly named to the list of references for the project the item is being added to. Here, the System assembly is referenced by its full, strong name. The <References> tag is available only for new item templates and not in new project templates. Any references for project templates are already specified within the project file, so references for new projects are not necessary. You can use the <References> tag to prepare a project so that it will build correctly without the user needing to manually add references.

The final type of template is the project group. If you are trying to package a group project for installation in a VSI file, then the TemplateType attribute should be set to ProjectGroup. Rather than using the Project tag as you do for new projects, the <ProjectCollection>tag is used within the <TemplateContent> tag. Within this tag, you can combine the <SolutionFolder> tag to create a new solution folder within the solution and a <ProjectTemplateLink>tag to reference another .vstemplate file. If the <ProjectTemplateLink>tag is given within a <SolutionFolder> tag, the new project will be created within the new solution folder. Any <ProjectTemplateLink>or <SolutionFolder> tags that appear directly under the <ProjectCollection>tag will create the project or solution folder in the location where the project group is added to the solution.

  <TemplateContent>   <ProjectCollection>    <SolutionFolder Name="Folder1">     <ProjectTemplateLink ProjectName="ConsoleApp1">       ConsoleApplication\csconsoleapplication.vstemplate     </ProjectTemplateLink>    </SolutionFolder>    <ProjectTemplateLink ProjectName="ConsoleApp2">       ConsoleApplication\csconsoleapplication.vstemplate    </ProjectTemplateLink>   </ProjectCollection>  </TemplateContent> 

<SolutionFolder> has one attribute, Name, that is used to name the solution folder that is created, whereas <ProjectTemplateLink>has one optional attribute, ProjectName. The value of this attribute is used to name the new project, but if it is not given, the name of the .vstemplate file without the extension, in both uses of the <ProjectTemplateLink>tags in this example, is csconsoleapplication. When a <ProjectTemplateLink>tag is encountered, the template wizard will gather together all the necessary information (such as where the project is to be created, the name of the new project, and so on), and then spawn off a new instance of the template wizard and create the new project. All replacements in the subproject are processed just as if the project were being created as a new project, and any values from the subproject (such as replacement values) will not propagate back up into the project group wizard replacements. When the new projects are added to the solution, the .vstemplate of those subprojects are searched for relative to the location of the group project .vstemplate file. In this example, the folder containing the group project template is prepended to ConsoleApplication\csconsoleapplication.vstemplate, and then the template wizard is run on the template file located at this computed path.

Wizard Data

The <WizardData> section of the .vstemplate file allows you to store freeform data in the .vstemplate file. One or more of these XML blocks can appear as a child of the <VSTemplate> tag, and one such <WizardData> XML fragment is shown here:

 <WizardData Name="MyWizardData">Some user defined data here.</WizardData> 

The data within a <WizardData> tag can be of any XML-representable data you may want, meaning it can be more XML, or, as in this example, just some plain text. When the template wizard reads in the .vstemplate file, any VSTemplate/WizardData tags that are found are read into memory, the Name attribute is read, a $ character is added to the beginning and end of the name, a replacement value is created with this name, and then the replacement value is set to the data within the <WizardData> tag. So, for this example, a replacement variable named $MyWizardData$ is created and the value of this replacement is set to "Some user defined data here." You can then use this replacement value in your source files. This will allow you to create custom replacement values and make replacements in your files just by modifying the .vstemplate file. You could even pack all the contents of source files into the .vstemplate file and then create files that have nothing more than the replacement argument name.

Storing the Template on Disk

After you have created your .vstemplate and source files, you need to place them in a location so that Visual Studio can find and display your templates in the New Project and Add New Item dialog boxes. But first, you must place all the necessary files into a .zip file—simply zip all the files, such as the .vstemplate, source, and project files, into one .zip file. You do not need to rename the file to have a special extension as you do for .vsi files; the extension .zip will do. After the files have been zipped, you need to copy the file into one of four folders so that they can be found. We have already seen the path of two of these folders when discussing the VSTemplate content installer. The folder C:\Documents and Settings\UserName\My Documents\Visual Studio 2005\Templates has two subfolders, ItemTemplates and ProjectTemplates. When the New Project or Add New Item dialog boxes are shown, Visual Studio will examine the appropriate directory for new, deleted, or modified .zip files and make the necessary updates to show the correct template in the dialog box. However, only the user whose My Documents folder has been modified will see changes made to these two folders.

What if you need to install a template that is available for all users of a computer? To make a VSTemplate available to all users, you need to place the template file in a location that all users can read from. The My Documents folder is readable only by the owner of that folder, so this is not an appropriate location for templates all users can invoke. The folders that are available to all users and where Visual Studio will look are either C:\Program Files\ Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates for project or group projects, or C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplates for project items. Under these folders are subfolders such as CSharp, JSharp, VisualBasic, and Web. Within each of these folders are more folders, which further qualify how and in which dialog box the template can be invoked by the user. After you have selected the folder in which to place your template, you then need to force Visual Studio to recognize the template. Because the .zip files for a VSTemplate are stored in the Program Files folder, a location that only users with elevated permissions (such as an Administrator) can write to, Visual Studio does not try to extract these .zip files every time the New Project or Add New Item dialog boxes are shown. Checking a folder that is changed infrequently would incur a performance hit. So to force Visual Studio to install a template for all users, after copying the file into the appropriate folder, you need to run the command ProgramName/setup from a command prompt, where ProgramName is devenv, vbexpress, csexpress, vwdexpress, or another for the appropriate program that you are setting up the template for.

Wizard Extensions

Although the template wizard does all of the work necessary to process a .vstemplate file, there might be times when you need to customize how a project or project item is generated. For example, suppose you need to display UI to the user to configure how the template is generated, or maybe you need to copy some files into the global assembly cache (GAC) before the project is created so that the project will run correctly, or maybe you need to modify one of the replacement parameter values to your own specification before the .vstemplate file is processed. With a wizard extension, you can easily add to the template wizard the ability to run your own custom code at opportunistic times when the project, the project item, or the group project is being created.

To create a wizard extension, you will need a class library that implements a specific interface, and information about the wizard extension needs to be added to the .vstemplate file. The definition of this interface is contained within the assembly Microsoft.VisualStudio. TemplateWizard.dll. The methods of this interface, which you need to implement, are as follows:

  • void RunStarted(object automationObject, System.Collections.Generic. Dictionary <string, string> replacementsDictionary, Microsoft.VisualStudio. TemplateWizard.WizardRun Kind runKind, object[ ] customParams) This method is called just after your wizard extension has been loaded and before the TemplateData section of the .vstemplate file starts to be processed. This method provides you with data such as the automation model (an instance of a DTE object) of the application running the wizard passed through the applicationObject parameter. The runKind parameter provides you with an enumerated value that can be AsNewItem if the wizard is being invoked to add a new item to an existing project, AsNewProject if a new project is being created, or AsMultiProject if a group project is being added to a solution. The customParams argument provides a way for the host application to pass context-sensitive information to the wizard extension, but this array usually contains 0 elements. But the replacementsDictionary is the argument that gives you the most power over how the template wizard processes a .vstemplate file. Table 4-2 listed replacement values that the template wizard will search for in files within the project or project item that is being created. The replacementsDictionary contains a list of the tokens to replace and the values that will be used to replace with. This Dictionary object can be read from and written to, meaning that you can modify, add, or remove the values that replacements will be made with. The RunStarted method is also a good place for you to display any UI that might be necessary for configuring your template; you can combine any user input from UI to modify the dictionary and control how the template is rendered.

  • void BeforeOpeningFile(EnvDTE.ProjectItem projectItem) This method is called just before a file is opened. The OpenInEditor="true" attribute on the ProjectItem tag must be specified for the item to be opened.

  • void ProjectFinishedGenerating(EnvDTE.Project project) This method is called when all processing to create a project is complete, the project has been loaded into the solution, and the project is open. You can use the automation model for the project to do any further manipulations that might be necessary. This method is called only when a new project or project group is being created; it will not be called for Add New Item templates.

  • void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) ProjectItem FinishedGenerating is similar to the ProjectFinishedGenerating method, except this method is called when an Add New Item template is processed.

  • bool ShouldAddProjectItem(string filePath) This method is called when an Add New Item template is processed, and it is supplied the file path of the item that is being generated. If you return true from this method, the item will be added to the project, and if you return false, the item will not be added to the project. This method is useful for wizards that show UI, and, based on the input from the UI, this method selectively adds files to a project. The Visual Web Developer Add New Item templates use this method for the Place Code In Separate File check box in the Add New Item dialog box. The new Web Service template has three project item files listed: WebService.asmx, WebService_cb.asmx, and CodeBehind.cs. If the Place Code In Separate File check box is selected, this method returns false for the WebService.asmx file, while the value false is returned for WebService_cb.asmx and CodeBehind.cs files if the check box is not selected.

  • void RunFinished() After all processing of a .vstemplate file is complete, the wizard will call this method allowing you to perform any cleanup your code needs to do.

After you have created your wizard extension, you must place the assembly implementing the extension in a place where Visual Studio can find and load it. For security reasons, the assembly must be in either the directory containing the executable for that application (such as the folder containing Devenv.exe), a subdirectory containing the executable, or a directory listed in the .config file for the executable (such as Devenv.exe.config) in the probing section of the XML. This security restriction is in place because you do not want templates installed through the Internet with the Content Installer to be able to execute code. Suppose you were to download template content from the Internet and create a project from that template. If the VSTemplate .zip file contained an assembly implementing IWizard, and the .vstemplate file referenced that assembly, when the project is created it will cause that code to run. You can see how this is an easy way for a malicious hacker to place code on your computer, and the innocent action of creating a project would run that code. Templates from the Internet can still run code through a wizard extension, but if you need to have elevated permissions (such as Administrator permission) to install an assembly into one of the special directories from which an assembly will be loaded, you minimize the risk of installing bad templates, but you still provide the ability to run wizard extensions. This also means that if you are creating wizard extensions, you need to make sure that your IWizard extension cannot be used to cause harm to a user's computer.

Creating a new wizard extension is easy with the WizardExtension starter kit. This starter kit, which is available with the samples for this book, will create a C# class library that implements the IWizard interface and create a fragment of XML that you can paste into a .vstemplate file. All you need to do is supply the .vstemplate and copy the .dll file into the correct location so that it can be loaded.

Security Attributes

You can strengthen the security of a wizard extension through the use of attributes. Much as you can place attributes into your IImportCommunityContent implementation of a custom installer to restrict which content can be installed, you can place attributes on your class implementing IWizard to restrict which templates can call into your assembly. The TemplateWizardDisallowUserTemplatesSecurityAttribute attribute takes a Boolean value. If this value is true, then only templates that are installed into the Program Files\ Microsoft Visual Studio 8\ location can call into your wizard extension, and templates installed into the My Documents location cannot load and call the extension. If this value is false (the default), any template, regardless of where it is stored, can call into the wizard extension. Another attribute, TemplateWizardSecurityAttribute, limits which template can call into your wizard extension. This attribute takes a string that is the file name without full path information, but with the .vstemplate extension of a template that can call the wizard extension. When the template wizard loads the wizard extension, it first checks for the TemplateWizardSecurityAttribute. If it is found, it compares the string passed to the attribute with the file name of the template. If the two strings match, the wizard extension will be loaded and run. If it does not match, the wizard will not be loaded. Multiple TemplateWizardSecurityAttribute attributes can be placed on the class implementing the wizard extension so that you can call the extension from multiple templates. If you are using the TemplateWizardSecurityAttribute attribute, you should also be using the TemplateWizardDisallowUserTemplatesSecurityAttribute attribute. If you were to use only the TemplateWizardSecurityAttribute attribute and you specified the template name as MyVBTemplate.vstemplate (with the intention to restrict calling the extension from within the Program Files\Microsoft Visual Studio 8\ location), the user could download from the Internet a template that contains the file MyVBTemplate.vstemplate and then your wizard extension would run. By using these two attributes together, you will make sure that the only templates that will run are those the wizard extension was built to aid.




Working with Microsoft Visual Studio 2005
Working with Microsoft Visual Studio 2005
ISBN: 0735623155
EAN: 2147483647
Year: 2006
Pages: 100

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net