SkillAgentSearch skills...

ProjectTemplateTutorial

A tutorial on how to create a project template for Visual Studio.

Install / Use

/learn @dogtail9/ProjectTemplateTutorial
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Project Template Tutorial

This is a tutorial on how to create a project template for Visual Studio with multiple projects, commands, dialogs and external tools. The project template will have a mandatory and an optional project that you can choose from a dialog when the project is created. There will also be an item template that uses Text Template Transformation Toolkit (T4) to generate code from a DSL.

Step 0 : Prerequisites

I have the following softwares installed on my machine.

If you download the code from GitHub you have to change the debug settings for the VSIXProject to be able to debug.

  • Start Action : C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe
  • Command line arguments: /rootsuffix EXP

Change the debug settings for the VSIXProject when downloaded the code from GitHub

If you want to skip some steps in this tutorial, you can download the code and begin on the following steps

Step 1 : Create a custom project template

In the first step, we will create a VSIX Project, add a project template with a wizard (the SolutionWizard), where we by code could add other project templates to the solution.

Solution

First we need a solution. Open Visual Studio and follow the steps bellow.

Choose the blank solution project template

Now we have our solution that we can start adding project to.

VSIX Project

The VSIX project where we will put all logic such as wizards, commands and dialogs.

Add a VSIX Project to the solution

Delete the unnecessary files

Add folders for Commands, Dialogs and Wizards

Solution Project Template

Add a project template whose sole purpose is to run a wizard where we can add the code to create our project. I add all my template projects to a solution folder called ProjectTemplates.

Add the solution project template

Delete the unnecessary files

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

Delete the content of the TemplateContent element in the ProjectTemplateTutorial.Solution.vstemplate file

Change the type attribute of the VSTemplate element in the vstemplate file to ProjectGroup

Add a category for the project template in the new project dialog

Solution wizard

Now we need to add a wizard class with the logic for creating our project template. Add a class to the Wizard folder in the VSIXProject, name it SolutionWizard. The SolutionWizard class should implement the IWizard interface. You also need to sign all projects in the solution.

Add the references to envdte and Microsoft.VisualStudio.TemplateWizardInterface in the VSIXProject

using Microsoft.VisualStudio.TemplateWizard;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EnvDTE;

namespace ProjectTemplateTutorial.VSIXProject.Wizards
{
    public class SolutionWizard : IWizard
    {
        public void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public void ProjectFinishedGenerating(Project project)
        {
        }

        public void ProjectItemFinishedGenerating(ProjectItem projectItem)
        {
        }

        public void RunFinished()
        {
            int i = 0;
        }

        public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
        }

        public bool ShouldAddProjectItem(string filePath) => true;
    }
}

The SolutionWizard class

Set a breakpoint in the int i = 0; line in the RunFinished method.

Assets

The only thing left to do is to add assets to the VSIXProject. Open the source.extension.vsixmanifest file in the VSIXProject. Add the assets below.

Add assembly

Add project template

Add the wizard to the solution project template

I use ILSpy to get the strongname of the ProjectTemplate.VSIXProject.dll

<WizardExtension>
  <Assembly>ProjectTemplateTutorial.VSIXProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b490d4518b7bc751</Assembly>
  <FullClassName> ProjectTemplateTutorial.VSIXProject.Wizards.SolutionWizard</FullClassName>
</WizardExtension>

Add the WizardExtension element to VSTemplate element in the vstemplate file

Let´s try to create a project with our project template.

The project template is located in the tutorial category in the New Project dialog

The break point in the RunFinished method should be hit

An empty solution is created

We are done with the first step in this tutorial.

Step 2 : Mandatory project template

Let´s add the project template for the mandatory project. If you skiped the first step in this tutorial you can download the code from the Solution release and start the tutorial here.

Add the mandatory project template

We want to hide this project template in the New Project dialog and add the project to the solution from the SolutionWizard class.

<Hidden>true</Hidden>

Add the Hidden element to the TemplateData element in the ProjectTemplateTutorial.Mandatory.vstemplate file

Add the mandatory project template as an asset in the VSIXproject

Add the Microsoft.VisualStudio.Shell.14.0 NuGet package to the VSIXProject

Let's write the code to add the mandatory project to the solution. Visual Studio passes a dictionary with data from the New Project dialog to the wizard. We need to save this data and use it to create the mandatory project from our mandatory project template.

private Dictionary<string, string> _replacementsDictionary = new Dictionary<string, string>();
DTE _dte;

public SolutionWizard()
{
    _dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
}

Add a constructor and fields to the SolutionWizard class

public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
{
    _replacementsDictionary = replacementsDictionary;
}

Store the replacementsDictionary in the field in the RunStarted method

public void RunFinished()
{
    string destination = _replacementsDictionary["$destinationdirectory$"];
    string fileName = _replacementsDictionary["$safeprojectname$"] + ".sln";
    _dte.Solution.SaveAs(Path.Combine(destination, fileName));
    
    var projectName = $"{_replacementsDictionary["$safeprojectname$"]}.Mandatory";
    var templateName = "ProjectTemplateTutorial.Mandatory";

    AddProject(destination, projectName, templateName);
}

Get the data for our project from the replacementsDictionary and pass it to the AddProject method

We will use the DTE object to add the project to our solution. Later we will refactor this method to a helper library so we can reuse it in other project templates but for now just put the AddProject method in the SolusionWizard class.

private void AddProject(string destination, string projectName, string templateName)
{
    string projectPath = Path.Combine(destination, projectName);
    string templatePath = ((Solution4)_dte.Solution).GetProjectTemplate(templateName, "cs");

    _dte.Solution.AddFromTemplate(templatePath, projectPath, projectName, false);
}

Code to add the a project to the solution

Let's try the project template to see it the mandatory project is created.

The mandatory project is created

You can also add projects and use the build in project template if you like. You find the build in project templates in the C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\ProjectTemplates folder.

projectName = $"{_replacementsDictionary["$safeprojectname$"]}.WCFServiceLibrary";
AddProject(destination, projectName, "WcfServiceLibrary");

Add a WCFServiceLibrary to the solution

*The project cr

Related Skills

View on GitHub
GitHub Stars15
CategoryDevelopment
Updated6mo ago
Forks3

Languages

C#

Security Score

82/100

Audited on Sep 10, 2025

No findings