Visual Studio Item Templates, Custom Wizards and VSIX installers

The definitive guide on creating your own Visual Studio templates with a fully functional sample solution

News flash You can create your own item and project templates for use with Visual Studio! Well I guess this is not really so big news if you've used the IDE for a while.

Templates for files housing source code, resource configurations, configuration files and many other things can in many cases quickly out weigh any cost that it entails creating one. Especially if you're working on a large team or that your code base requires a fair amount of tedious but important boilercode for new source files (even things like header comments can be a huge timesaver).

A custom item template in the <i>Add New Item</i> dialog

A custom item template in the Add New Item dialog

So we all know that these things can be created. What is surprising is really how easy it is to create them.

There are numerous sources all over the internet that discuss how to create both simple item templates and larger more complex project templates. Here are a few good ones: #1, #2, #3, #4, #5, #6, #7 but really they are too numerous to list here. So for this article I will not go into the details of the actual creation as it is fairly mundane.

What is however hard to comeby is a complete actual working example of one. This is what I have for you!

See the code

In addition to the complete example solution I also want to focus on the nitty-gritty issues that crop up when composing these types of projects that very few sources seem to discuss in any detail.

The project structure

This is an overview of the current example solution I am offering. Just having a reference to what goes where and what references are useful where can be very helpful, so here you go.

The complete file structure of the solution

The complete file structure of the solution

Choose correct project types

After installing the Visual Studio Extension SDK it is very important that you choose the correct project types. These are all found under the Visual C# > Extensibility category.

Yes even though you're creating a C++, F# or a template for what ever other language, the project housing the templates and relevant code will always be in C#.

Ensure you use the correct item tags

The .vstemplate file that contains the configuration for your Item or Project template must be configured as a <VSTemplate> item in the template .csproj file, Example. This setting is controlled via the Build Action for the .vstemplate files. Ensure that this is correctly set, otherwise your files will not be built and packaged correctly.

Choose build action <i>VSTemplate</i> for all .vstemplate files

Choose build action VSTemplate for all .vstemplate files

When you create a new project from scratch this value is correctly set for the existing file. However when you add your own files in there this is a very common oversight to make.

Keep your Wizard code in the VSIX installer project

This is by far the simples approach and requires only two projects. If you really really need a third project for the wizard code then this is not a huge problem but can be a bit of a headache to setup in the VSIX installer configuration (hint: use dependancies).

The Wizard code cannot belong to the Template project as the output of this project will not be a dll but a zip file containing your templates.

Finding the correct dlls for the Custom Wizard

The two external dll includes you need for the custom wizard logic are the Microsoft.VisualStudio.TemplateWizardInterface.dll and envdte.dll. It is very likely that there are multiple versions of these dlls floating around on your computer.

Choose the ones that were shipped with the Visual Studio edition you're building your project in and/or the version of the IDE that you're specifically targetting.

For me this means including these versions:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.TemplateWizardInterface.dll

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte.dll  

You must sign the Wizard assembly

For Visual Studio to even consider loading the dll containing your custom wizard implementation you must sign the assembly containing that code. It is not a biggie and just means you need to specify the fully qualified name of the assembly in the .vstemplate file.

I really love this trick to set up an External Tool to extract the PublicKeyToken for the assembly.

  1. Tools > External Tools
  2. Add new one and use the following config
  3. Command: path/to/your/sn.exe Arguments: -T $(TargetPath) Check: Use Output window
  4. In the Solution Explorer: Select the assembly and run your newly created tool.

When testing your extension Visual Studio can get confused

A common error to crop up is the "GetDeploymentPathFromVsixManifest" task failed unexpectedly. This error occurs for no apparent reason, usually after you've been able to build the solution quite a number of times without errors.

This error is due to the existence of certain folders and files under your $APPDATA directories that relate to running the Experimental versions of Visual Studio (which is done when you debug your extension).

The example solution includes a bat file VSItemTemplateVISX\prebuild_clean.bat that will remove all these unnecessary files for you in-case you encounter this error.

You will have to shut down your Visual Studio instance before running the command

The contents of the batch file

The batch file simply attempts to delete the *_Exp folders that were created for your Experimental instances from your local AppData caches. The entire bat file contents are below for completeness.

set VS_PATH=Microsoft\VisualStudio

REM First check Local/AppData 
cd %LOCALAPPDATA%\%VS_PATH% 

for /f %%G in ('dir /b "*Exp"') do ( 
    echo Found %%G 
    rmdir /S /Q %%G 
)

REM Second check the main AppData path
cd %APPDATA%\%VS_PATH% 

for /f %%G in ('dir /b "*Exp"') do ( 
    echo Found %%G 
    rmdir /S /Q %%G 
)

Details about the problem

The actual problem lies in the fact that Visual Studio locks the following three files

privateregistry.bin
privateregistry.bin.LOG1
privateregistry.bin.LOG2

You can get away with just deleting them but removing the entire _Exp folder does no harm and potentially avoids other issues if you leave out of date Experimental files in there.

Conclusion

Well that is it. The example solution should speak for itself and the points above highlight the biggest pains that I had while attempting to create my first template installer.

Hope this is of use and as always drop me a line in the comments if you have something to add or any questions.

See the code



Software Developer
Contact Me


Developer & Programmer with +18 years professional experience building software.