P3.NET

Creating Item Templates in Visual Studio 2017

Many times when you are adding a new item to a project you probably find yourself changing the generated item to line up with your coding or company styles. Often this includes a copyright, perhaps the ordering of members in a type or even completely replacing the item with something else, like an enum. Visual Studio is designed to be extensible. Item templates allow you to create your own templates and have them available in VS so you don’t have to keep making the same changes over and over again. In VS 2017 templates are even easier to create than before. I will discuss how easy it is to add new templates in this article.

Item Templates

Before creating an item template you need to understand what it is. Open any projects in VS and then right click the project and select Add and then any item under there (eg. New Item). What pops up is Add New Item dialog. Each of these is an item template. Item templates can come from anywhere including the core VS installation, extensions you install later and from the file system. Under your Documents folder where VS stores your information is a folder where it looks for your custom item templates (default for VS 2017 is Visual Studio 2017\Templates\ItemTemplates.

Templates are designed to quickly allow you to add new files to your projects without having to redo the same changes each time. While you can edit the provided templates I would not recommend it for several reasons. Firstly the changes may get lost on the next update. Secondly reinstalling VS would wipe the templates and templates between versions may change. Thirdly, sometimes you really do want the original templates available so replacing them is not a good idea.

Creating a new template really just involves creating the skeleton file(s) with the content you want and adding some metadata so VS knows what to display. Unfortunately templates are very limited in what they can do. Any sort of programmatic changes will require using a wizard instead.

Extension Class Template

Extension classes are pretty common in code these days so we’ll create a template that handles this for us. The easiest way to get started is to take an existing extension class and make it generic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    /// <summary>Provides extension methods for SomeType.</summary>
    public static class SomeTypeExtensions
    {
        public static void DoSomething ( this SomeType source )
        {
        }
    }
}

Now to make it reusable. Firstly the user will provide a name for the new item when they create it so we want to use that as the class name. In a template you can use the $safeitemname$ value. Find all places in the file that use the class name and replace them. Notice the parameter is called –safe. VS will remove characters from the name that are not valid as identifiers.

The namespace should follow the default project namespace. Additionally the folder in which the item is dropped into should be included to follow convention. Fortunately there is a parameter for that as well $rootnamespace$. Replace the namespace name with this as well. Sidenote that MSDN mentions that you can use $safeprojectname$ for the namespace but this does not appear accurate. When used in an item template it does nothing. The documentation for the parameter mentions it is for the New Project dialog and therefore isn’t valid for item templates.

Finally, just for fun we’ll add a copyright notice. This time we’ll use the $year$ parameter which puts the current year in the file. The full list of available template parameters is defined here. Here’s the final template.

/*
 * Copyright © $year$ My Company
 * All Rights Reserved
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace $rootnamespace$
{
    /// <summary>Provides extension methods for SomeType.</summary>
    public static class $safeitemname$
    {
        public static void DoSomething ( this SomeType source )
        {
        }
    }
}

VSTemplate File

Now that the item skeleton is complete we need to let VS know about it. To do that we need to create a vstemplate file. A vstemplate file is an XML file that describes the template, where it should be placed and what file(s) make it up. Here’s a standard example.

<?xml version="1.0"?>
<VSTemplate Type="Item" Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name>Extension Class</Name>
    <Description>Creates an extension class.</Description>
    <Icon></Icon>
    <ProjectType>CSharp</ProjectType>
    <DefaultName>MyExtension</DefaultName>    
  </TemplateData>
  <TemplateContent>
    <ProjectItem ReplaceParameters="true" TargetFileName="$fileinputname$.cs">ExtensionClass.cs</ProjectItem>
  </TemplateContent>
</VSTemplate>

Let’s take this file apart. The VSTemplate element identifies whether this is a project or item template. Within this element is the template metadata and content. The TemplateData element defines the metadata for the template. The TemplateContent element defines the file(s) that make up the template.

Name (required)
The name of the template as shown to the user
Description (required)
The description of the template as shown to the user
Icon (required)
The icon file of the template
ProjectType (required)
The type of project the template works with (CSharp, VisualBasic, VC or Web)
ProjectSubtype
The subtype of project the template works with

The documentation for vstemplate files is defined here but be aware that this file is used for both item and project templates. Some elements are only meaningful for one or the other. Read the documentation carefully to ensure you can use an element.

Note that previous versions of VS supported using a resource DLL for some of the values. For performance reasons it is recommended that you do not do this going forward.

The project type and subtype values are tied together. For a C# project you can specify a type of CSharp and leave subtype off. But for a web project you need to specify the type as Web and the subtype as CSharp. A full discussion is available in MSDN.

Template Content

Under the TemplateContent is a ProjectItem element for each file that is part of the template. Yes you can have multiple files in a template. The value of the element is the name of the file inside the template. All attributes are optional.

TargetFileName
The filename to use in the project (generally set to $fileinputname$.cs or similar)
ReplaceParameters
Indicates whether the file contains template parameters that should be replace (generally set to true)
Subtype
The optional editor to use for the file (generally only used for nested files)
CustomTool
The optional custom tool to associate with the file

While not needed here, you can also have a References element which child Reference elements. You can use this to add assembly references to a project when the item is added. You can read more about them here.

The last thing you’ll want to do is create an icon file (or copy one) for the template. Ensure the filename matches what is in the template. Note that if you leave the icon element empty then a generic icon is used instead.

Installing the Template

Prior to VS 2017 you would need to zip up the vstemplate and content files and put them into one of the searched template paths. With VS 2017 not only do you not need to zip them up anymore but you are encouraged not to for performance reasons. Instead all you need to do is drop the files into a folder in one of the search paths and VS will find them.

For local templates you can put them in the documents folder as mentioned earlier. For shared templates place them someplace everyone on the template has access to and ensure VS is updated to use the shared template location. When looking at the template structure that is generated by VS you’ll notice it is broken up by language. For a C# template you’ll want to put your templates in the Visual C# folder. The same goes for the other languages.

Create a folder for your template (e.g. ExtensionClass). Now copy your content files, icon file and vstemplate file into the folder. In my experience VS will only look for templates once so restart VS after dropping the template into the folder and then open a project and select Add\New Item again. You will probably need to scroll but you should find your template. Select it, enter an item name and verify the item is added properly.

Now that you have one template working, it becomes easy to simply copy/paste the folder structure, change the template contents and update the vstemplate file to create new ones. Using your own custom templates should greatly speed up your development.

A final note on the folder structure. The documentation mentions that you can create template categories to group your templates together by creating a category folder in the root of the language template folder and then create your template folders under that. It indeed does work for extensions but custom templates don’t appear to work. If you put an intermediate category folder under the language folder then VS will ignore your template. Whether this is a bug or not I cannot say.

Template Wizards

The templating engine built into VS is pretty limiting. If you want to make more complex templates then you will have to define a template wizard. Creating a wizard is beyond the scope of this post but I created one a while back in my series on creating environmental config transforms using T4. The vstemplate file needs to be updated to point to the wizard if you go this route.

Exporting Templates

The approach I talked about here is a completely manual process for creating templates. If you already have a file defined in a project that you want to reuse elsewhere then you can export the file (or even the project) using the Project\Export Template option. Note that this generates a template but does so following the older rules. You can read more about exported templates in MSDN.

T4 Templates Update for Visual Studio 2015

A while back I posted a series of articles on how to use T4 and a custom VS extension to simplify some common code like application settings, WCF clients and environmental transforms. With the release of Visual Studio 2015 I had to update my own extension and templates so I wanted to posted a follow up article on the changes that need to be made to allow the extension to work with Visual Studio 2015. As part of the update I added some functionality to the app settings template. Before continuing be sure to download the previous version of the series (or simply download the final version below).

Read More

BuildVer Update

UPDATE: A new update (v2.1) that resolves a few issues:

  • Character set conflicts when using non-ASCII characters
  • Updated documentation on how to integrate version.rci without having VS delete it the next time you open the resource designer
  • Fix for parameters that are built from the product version

I recently had the need to update my BuildVer tool to use in newer projects.  BuildVer is an incremental versioning tool that can be used for automated builds.  It was originally written to allow us to use the Win32 VERSIONINFO resource but have it updated for each build.  Later functionality was added to support generating standard .NET assembly info files.  While the existing tool was sufficient I decided that it was time to update the code and, at the same time, add some new features.

The original code was written over a decade ago in C++.  Later it was updated for .NET support and to use MFC types.  The new tool is completely written in C#.  The original version could generate 1 or 2 files (a managed and unmanaged file) and an optional text file.  Some support was added for specifying the build information on the command line.  This was sufficient to meet the needs of the time.

v2 supports generating any number of output files with their corresponding template files.  The tool works with any text file.  Additionally the configuration file has been expanded to allow for specifying arbitrary parameter name-value sets that can be used in template files.  There are a couple of pre-defined sets for versioning, company information, etc.  Any of the parameter values can be overridden by the command line.  This allows for more flexibility in the tool while keeping the command line options concise.

The readme.txt file contains all the details.  The attached file contains the source code and a v4 version of the tool along with sample templates for C# and C++.  Feel free to use the tool as you see fit.  One note however, some of the code in the tool (specifically the command line processor) is copyright Carlson Engineering, Inc. and may not be reused without explicit permission.  You can compile and use the tool itself without permission. 

UpdateUserType (Visual Studio Addin)

Here is another addin I wrote for VS2008 and then updated for VS2010.  In C++ you can define your own custom keywords and VS will color them differently if you say so (ToolsOptions -> Fonts and Colors).  There are a couple of problems with the VS solution.

  1. You have to edit the UserType.dat file.
  2. You have to restart VS.
  3. You have only one set of keywords for all of C++.

The second and third problems are the killers here.  As you are developing code you will often find a set of keywords you’ll want to add.  To do so you’ll have to open the .dat file, add the keywords and then restart VS.  Even worse is that if you are working on an MFC project then you’ll likely want some MFC keywords but if you switch to Win32 then you want a different set of keywords.  To resolve this problem you’ll have to keep multiple .dat files that you can swap in and out.  Enter UpdateUserType.

UpdateUserType does a couple of things. Firstly it allows you to separate your keywords into different files (i.e. C++, MFC, Win32).  Secondly UpdateUserType can merge all these files into a single .dat file.  Thirdly the addin will detect when the .dat file changes and request VS to refresh its keyword list.  

Using the addin UI you can add a list of .txt files to be monitored.  Whenever one of these files is modified the addin merges them all into a new .dat file.  This allows you to separate keywords by area and enable only the keywords appropriate for your current project.  My personal technique is to keep one or more of them open in a separate editor so that I can add new keywords as I go through code.  Saving the files in the editor causes the .dat file to be regenerated.

When the .dat file changes the addin requests VS to refresh the keyword list.  When this happens VS will read the .dat file and begin coloring the keywords again.  This feature allows you to add keywords on the fly and have VS begin coloring them almost instantiately. 

Attached is the source and binaries for the VS2010 version of this addin.  Additionally I’ve included some starter .txt files that you can use.  A caveat is in order.  The .XML file where the addin stores the files to be merged supports relative or absolute paths.  However the UI and the code only supports absolute paths.  Therefore if you use the UI to change the file list then the paths are converted to absolute paths.

To install the addin copy the contents of the Bin directory to your %My Documents%Visual Studio 2010Addins directory.  You might need to enable the addin via ToolsAddin Manager.  If the addin does not show up (it’ll appear under the Tools menu) then you might need to force a re-registration.

CodeHTMLer (Visual Studio Addin)

CodeHTMLer is a utility written by Weshaggard and available here.  The utility allows you to convert code to HTML for insertion into a website or blog.  It happens to be the tool I use for code on this site.  I know, I know.  There are many tools already available for this but I prefer CodeHTMLer for several reasons.

  1. It supports multiple languages.
  2. The HTML is partially configurable via the XML file it loads.
  3. Some code elements can be ignored rather than having to generate style information for everything.
  4. Can use either existing CSS styles or inline styles.
  5. It is fast.

The only issue I had with it was that I wanted to use it inside Visual Studio.  Being a developer I did the logical thing and wrote an addin for it.  The addin was originally written for VS2008 and the updated for VS2010.  The attached code runs under VS2010.  The addin wraps CodeHTMLer and adds the following features.

  1. Copy as HTML is exposed as an option in the editor.
  2. A UI is added to allow you to change the options in the XML file to control how HTML is generated.
  3. Uses the VS code model to determine which language definition to use for formatting so you can format VB one way and C# another, for example.

I only ran into a couple of problems with CodeHTMLer.  These mainly revolved around the manner in which it expected to be used.  I had to modify (and annotate) the areas I changed.  Furthermore I needed a few additional options for controlling formatting so I extended the language definition code to add a few extra attributes along with the serialization logic.  So the version that is included here is a modified version of the one available from CodePlex.  As a final note the attached language definition file is modified to support how VS names languages.  The original version did not use the same name for C# as VS.

IMPORTANT: I don’t take credit for CodeHTMLer or any of its source.  I only take credit for the addin code.  Please support the original author for CodeHTMLer.

The current project is for VS2010 but you can recompile the code if you want a VS2008 version.  To use this code extract the binaries to your addin directory (%My Documents%Visual Studio 2010Addins).  In VS you probably need to enable the loading of the addin via the ToolsAddin Manager command.  If it does not show up then you might need to modify the addin file to force a re-registration.  The addin shows up as an item in the Tools menu and as a context menu option when you right-click in the code area.