Template Parameters
All templates support parameter substitution to enable replacement of key parameters, such as class names and namespaces, when the template is instantiated. These parameters are replaced by the template wizard that runs in the background when a user clicks OK on the New Project and Add New Item dialog boxes.
Declaring and Enabling Template Parameters
Template parameters are declared in the format $parameter$. For example:
-
$safeprojectname$
-
$safeclassname$
-
$guid1$
-
$guid5$
To enable parameter substitution in templates
-
In the .vstemplate file of the template, locate the ProjectItem element that corresponds to the item that you want to enable parameter replacement for.
-
Set the ReplaceParameters attribute of the ProjectItem element to true.
-
In the code file for the project item, include parameters in code where appropriate. For example, the following parameter specifies that the safe project name be used for the namespace in a file:
namespace $safeprojectname$
Reserved Template Parameters
The following table lists the reserved template parameters that can be used by any template.
Note |
|---|
| Template parameters are case-sensitive. |
| Parameter | Description |
|---|---|
| clrversion | Current version of the common language runtime (CLR). |
| GUID [1-10] | A GUID used to replace the project GUID in a project file. You can specify up to 10 unique GUIDs (for example, guid1). |
| itemname | The name provided by the user in the Add New Item dialog box. |
| machinename | The current computer name (for example, Computer01). |
| projectname | The name provided by the user in the New Project dialog box. |
| registeredorganization | The registry key value from HKLM\Software\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization. |
| 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 box, with all unsafe characters and spaces removed. |
| safeprojectname | The name provided by the user in the New Project dialog box, with all unsafe characters and spaces removed. |
| time | The current time in the format DD/MM/YYYY 00:00:00. |
| userdomain | The current user domain. |
| username | The current user name. |
| year | The current year in the format YYYY. |
Custom Template Parameters
In addition to the reserved template parameters that are automatically used during parameter replacement, you can specify your own template parameters and values. For more information, see How to: Pass Custom Parameters to Templates.
Example: Replacing Files Names
You can specify variable file names for project items using a parameter with the TargetFileName attribute. For example, you could specify that the .exe file use the project name, specified by $projectname$, as the file name.
<TemplateContent>
<ProjectItem
ReplaceParameters="true"
TargetFileName="$projectname$.exe">
File1.exe
</ProjectItem>
...
</TemplateContent>
Example: Using the Project Name for the Namespace Name
To use the project name for the namespace in a Visual C# class file, Class1.cs, use the following syntax:
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace $safeprojectname$
{
public class Class1
{
public Class1()
{
}
}
}
In the .vstemplate file for the project template, include the following XML when referencing the file Class1.cs:
<TemplateContent>
<ProjectItem ReplaceParameters="true">
Class1.cs
</ProjectItem>
...
</TemplateContent>
See Also
On x64 system it is located at HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
- 4/27/2010
- MarkA
- 9/19/2008
- Ryan Cook
I've found the following tokens which are not documented on this page:
$fileinputname$ | The unsafe file name (without extension) entered into the Add New Item dialog (see "$itemname$ and $safeitemname$" comment and "unsafe" comment above). Same for Multi-File item templates.
$fileinputextension$ | The extension of the file name entered into the Add New Item dialog. Same for Multi-File item templates.
$runsilent$ | unknown boolean
$itemname$ | The unsafe file name and extension entered into the Add New Item dialog box. Same for Multi-File item templates.
$itemrootname$ | Same as $itemname$
$rootname$ | Same as $itemname$
$safeitemrootname$ | The safe file name (without extension) entered into the Add New Item dialog. For Multi-File templates, this is the safe file name of the current template item being processed from the .vstemplate. I believe this Multi-Item behavior to be incorrect and have submitted a bug, please vote https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=247500
$rootnamespace$ | default namespace of the current project.
- 12/21/2006
- Ryan Rahlf
- 7/22/2008
- Stanley Roark
- 8/8/2007
- Paul Hatcher
Bill Hiebert & Stephen Rakonza recently helped me with this issue.
Bill concluded:
... the only way to do it is by writing an IWizard extension. Your wizard extension would add a new replaceable parameter based on the item name entered by the user. This new parameter would be used instead of $safeitemname$ in your file2.vb.
Stephen sent this information on creating the wizard:
http://dotnet.sys-con.com/read/315033.htm
Yes there's documentation on MSDN as well. It's just a matter of deriving from the IWizard class and overloading a few methods. The article puts the wizard into the GAC. This isn't necessary; but there are restrictions (for security reasons). It needs to be in a 'trusted'
location. Under 'Program Files\Microsoft Visual Studio\Common7\IDE...'
would be a trusted location (since you need privileges to put a wizard there).
I hope this helps!
In multi-file file item templates, the $itemname$, $safeitemname$ and the undocumented $safeitemrootname$ tokens do not reflect the "name provided by the user in the Add New Item dialog box" but rather the file name without extension (and safe file name respectively) of the file being parsed in the multi-file template.
For example, if your .vstemplate contains two C# ProjectItem items with TargetFileName attributes of "Class1" and "Class2", then in the Class1.cs file these tokens will be replaced with "Class1" and in the Class2.cs file these tokens will be replaced with "Class2".
Unfortunately, this behavior is counter to the explanation in the January 2006 MSDN Magazine article Create Reusable Project And Item Templates For Your Development Team , particularly the $safeitemrootname$ explanation in figure 10.
Multi-File templates at MSDN
January 2006 MSDN Magazine, Create Reusable Project and Item Templates for Your Development Team :
Figure 10
- 12/20/2006
- Ryan Rahlf
- 12/21/2006
- Ryan Rahlf
In this help topic, the word unsafe is used to mean a string which is valid to be used as an identifier within the target programming language. This means that if you enter a project name of 123MyProject and the programming language is C#, the $safeprojectname$ replacement variable will be set to _123MyProject. If the project name given is @MyProject, the $safeprojectname$ value will be _MyProject.
All invalid characters are replaced with the underscore character, and if the first character is valid for the programming language, but not in the first character, then the underscore character is prepended.
- 6/11/2006
- Craig Skibo - MSFT
- 6/11/2006
- Craig Skibo - MSFT
All the $guidx$ replacement variables are of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, and do not include the surrounding { and } characters. This was done because some places, such as when assigning a GUID to a .NET component through an attribute, the surrounding braces are not needed. If you do need the braces, you can place them into the text file, such as this:
{$guid1$}
- 6/11/2006
- Craig Skibo - MSFT
When the $time$ replacement variable is rendered into a template, the current time is found by calling DateTime.Now.ToString(CultureInfo.InvariantCulture). This means that the date/time is not formatted to use the settings of the current culture, and it will always be in the form DD/MM/YYYY HH:MM:SS.
To work around this, you can create a wizard extension that replaces the $time$ replacement variable with the value DateTime.Now.ToString().
- 6/9/2006
- Craig Skibo - MSFT
Note