Usually, there is no need to create your own Visual Studio project template. The existing ones should suffice for most cases. However, if you find yourself often creating new projects and manually adding the same files or references to them; creating a new project template might make sense. It will save you time and prevent minor variations between the projects.
This article is published from the DNC Magazine for .NET Developers and Architects. Download this magazine from here [Zip PDF] or Subscribe to this magazine for FREE and download all previous and current editions
Preparing the Desired Project
The starting point for any new project template is another Visual Studio project, structured exactly as you would like a new project to look like, when you create it. As an example, we will prepare a new class library project, which you could use for trying out small code snippets to answer questions in forums or solve programming exercises. It will contain two classes: one for the sample code and one for the tests. NUnit unit testing framework will be referenced as a NuGet package.
I will be using Visual Studio 2015 for all my samples. Unless mentioned otherwise, the experience is the same in Visual Studio 2013. Just replace 2015 with 2013 wherever it appears in the text. You can use Visual Studio Community Edition or any of the other editions, except Express.
Here are the steps for creating such a project:
- Create a new classic Windows desktop Class Library project and name it Sample.Project. Keep the option checked to create a directory for the solution.
- Delete the Class1.cs file that was added to the project automatically.
- Open the Manage NuGet Packages window for the project, search for NUnit and install its latest stable version. Note that the user interface in Visual Studio 2013 slightly differs from the screenshot below.
Figure 1: Install NUnit NuGet package
- Add a new class item named Sample.cs with the following code:
public int Run(int args)
- Add another class item named Tests.cs with the following code:
public void SampleData()
private void Test(int input, int expected)
var sample = new Sample();
var actual = sample.Run(input);
Build the project and run the test (you will need NUnit Test Adapter or a similar extension to run a NUnit based test inside Visual Studio). If it passes, the project is correctly configured and we can use it to create a project template from it.
Exporting the Project as a Template
The easiest way to create a project template is by using the Export Template Wizard that is built into Visual Studio. Just navigate to File > Export Template… to open it. On the first page you can choose between creating a project template or an item template (Project template in our case), and select the project you want to create the template from (Sample.Project in our case).
On the second page, you will have a chance to enter the name and description of the template, and select the optional icon and preview image. You can keep both options checked to automatically import the template (i.e. copy it to Visual Studio 2015\Templates\ProjectTemplates inside My Document folder) and open the output directory (as shown in the wizard).
Figure 2: Enter project template details
If you are not too demanding, your job is already done. The exported template is available when creating a new project in Visual Studio. If chosen, it will create the same initial structure as you have prepared it. If you are using NuGet 2.7 or newer, the NuGet package will automatically be downloaded before the build and the test will succeed when run. You can even send the generated Sample.zip file to other developers. As long as they copy it into Visual Studio 2015\Templates\ProjectTemplates subfolder of My Documents, it will work for them, as well.
This approach has a couple of drawbacks:
· You cannot publish a template packaged as a .zip file to Visual Studio Gallery, to make it publically available.
· There is no installer for the template; each developer must manually copy it to the right directory to install or update it.
· If you want to do any changes to the template, you need to change your source project and repeat the export procedure.
· You cannot customize the project creation in any way, except for the automatic namespace and assembly name changes in the included source code files.
To avoid these downsides, you will need to take the longer route and create two more projects in your solution: a project template project to customize the created template and a VSIX project to distribute it as a Visual Studio extension. Both of them are available inside Visual Studio SDK.
If you are using Visual Studio 2015, Visual Studio SDK is a part of its setup package, but not installed by default: you must manually check the Visual Studio Extensibility feature during install. If you have not done so already, the only “project template” in Visual C# > Extensibility node will be Install Visual Studio Extensibility Tools. By double-clicking it, you will trigger the installation of the missing feature.
Figure 3: Visual Studio Extensibility Tools feature in Visual Studio Setup
Visual Studio 2013 does not come bundled with its extensibility SDK. Instead, it is available as a standalone download that you need to install separately.
Creating a Project Template Manually
Once you have Visual Studio extensibility tools installed, there is a Visual Studio project template available for creating customized project templates without using the Project Template Wizard. It is named C# Project Template and can be found in the Visual C# > Extensibility node of Add New Project Dialog. Create a new project from this template in your solution and name it Sample.Template.
A couple of files inside the created project require a closer look.
There are two AssemblyInfo.cs files in this project. The one in Properties folder is a part of the template project and can be safely ignored. The one in the root folder will be included in the generated template, but since it extensively uses template parameters (keywords enclosed between two $ characters), there is usually no need to modify it:
[assembly: AssemblyCopyright("Copyright © $registeredorganization$ $year$")]
A full list of supported template parameters is available in online reference documentation.
Class1.cs can be safely deleted, since we do not need it in our project. Instead, we need to add Sample.cs, Tests.cs and packages.config. I suggest you take them from Sample.zip created by the wizard and not from the initial project, because the fixed namespace is already replaced with $safeprojectname$ template parameter. Also, make sure you change the Build Action from Compile to None in the properties window for the .cs files, otherwise the build will fail because of invalid namespace name and other errors.
Sample.Template.vstemplate is the manifest file for the project template. It contains a list of all files that need to be included in the generated template; therefore, we need to change it in accordance with the changes that we have just made:
<Project File="ProjectTemplate.csproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.cs">
<ProjectItem ReplaceParameters="true" OpenInEditor="true">
<ProjectItem ReplaceParameters="true" OpenInEditor="true">
We have replaced the entry for the removed Class1.cs with entries for the newly added files. Although I am not going to describe every supported feature of TemplateContent element, I think it is appropriate to mention the ones used in the snippet above:
· ReplaceParameters attribute enables the processing of template parameters (e.g. $safeprojectname$) in the file. If it is disabled, the file will end up in the project unchanged. Any file containing template parameters, must have this attribute set to true.
· TargetFileName attribute can be used to move or rename the file in the generated project. In our case, AssemblyInfo.cs is moved to Properties subfolder.
· OpenInEditor attribute indicates which files will automatically be opened when the project is created from the template: Sample.cs and Tests.cs in our snippet.
In TemplateData element, only the following values need to be changed to give your template proper identity; the rest you can leave unchanged:
<Description>Answer a forum question or solve a programming exercise</Description>
If you want to further customize the manifest file, you can take advantage of IntelliSense in the editor, which lists available elements, attributes and values. For more information, consult the online documentation.
ProjectTemplate.csproj is the final file that requires our attention. You can either completely replace its contents with the file Sample.Project.cs from Sample.zip and overwrite the handling of different references for different target frameworks, or you can modify it manually to include the correct set of files and assembly references, which will require some knowledge of MSBuild:
· Replace the last ItemGroup listing the included source code files with the following two:
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sample.cs" />
<Compile Include="Tests.cs" />
<None Include="packages.config" />
· Add the following assembly reference to the ItemGroup just before these two:
<Reference Include="nunit.framework, Version=184.108.40.20650, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
Now you are finally ready to create the project template by building Sample.Template project in your solution. If you have done everything correctly, the build should complete without errors. You can find the output file Sample.Template.zip in the bin\Debug\ProjectTemplates\CSharp\1033 subfolder of the template project.
For testing, copy it to Visual Studio 2015\Templates\ProjectTemplates subfolder of My Documents and delete the wizard-generated Sample.Project.zip to avoid confusion. Now create a new project from the Sample template and notice how both Tests.cs and Sample.cs files are opened in the editor when the project is created. NUnit NuGet package is still restored before the build and the test still succeeds.
Packaging the Template as a Visual Studio Extension
To wrap the project template inside a Visual Studio extension, you will need to add another project to your solution. This time use the VSIX Project template (also located in the Visual C# > Extensibility node) and name it Sample.VSIX.
Now double click the source.extension.vsixmanifest file in the newly created project to open the editor window. Navigate to the Assets page and add Sample.Template as a new project template asset.
Figure 4: Add a new project template asset
The extension should now be ready for testing: just set Sample.VSIX as the startup project and press F5 to start debugging. This will cause Visual Studio to build the extension, run a new instance of Visual Studio using separate “experimental” configuration, and automatically install the extension inside it. When you try to create a new project in this Visual Studio instance, your template will already be available. It should work the same as it did, when you manually installed it, only without affecting your regular Visual Studio configuration.
Before distributing your extension to other developers or publishing it to Visual Studio Gallery, you should fill in the metadata in the common header of the extension manifest editor and on the Metadata page:
· Product Name will be shown as the title both in the gallery and in the Extension and Updates dialog in Visual Studio.
· Product ID must uniquely identify your extension. The default value includes a GUID; therefore, it should satisfy this requirement. You are free to change the value, just keep in mind that the gallery will not allow you to publish the extension, if another extension with the same ID is already published. Do not change this value between versions or you will break the update process for the extension.
· If you want updating of extension to work, you also need to increment the Version every time you publish a new version of the extension.
· Edit Author and Description fields as needed.
· It is a good idea to fill most of the other metadata fields as well, if you plan to put your extension in the gallery, as they will provide more information to potential users.
One last bit of information in the extension manifest that you might want to change, is on the Install Targets page. Here you can specify, which versions of Visual Studio your extension supports and can be installed into. By default the value will match the version of Visual Studio, you are currently using (14.0 for Visual Studio 2015, 12.0 for Visual Studio 2013), but you can specify a range of supported versions, e.g. [12.0, 14.0] would mean that the extension can be installed in both Visual Studio 2015 and Visual Studio 2013. Of course, you should still test your project template, to make sure it works correctly in all the listed versions. You can also change the product identifier, although the default choice of Community Edition and higher SKUs should be the right one for most cases.
The tooling for creating custom Visual Studio project templates is descent, but except for reference documentation in MSDN, there are not many resources about it. Even most of those were written for older versions of Visual Studio. The primary goal of this guide is to make you consider project template creation as another tool in your tool belt. If you decide to use it, this guide should be more than enough to get you started.
Download the entire source code from GitHub at bit.ly/dncm22-vs-proj-template