Creating Visual Studio ProjectTemplate VSIX package

How to create VSIX package for ProjectTemplate

  • Share

If you often have projects which setup is pretty much the same you might consider creating ProjectTemplate for Visual Studio.
It speeds up development for the project setup, adding references, default configuration .config, content files...

Before you start make sure that you have installed Microsoft Visual Studio 2013 SDK (http://www.microsoft.com/en-us/download/details.aspx?id=40758) and Nuget Package Explorer (http://npe.codeplex.com/)

I also attached a small dummy project just to help understanding what is written in this article.

Skipping to hands on code is always more helpful and faster for me to, so if you are bored by reading, download the attached .7zfile and explore it.

Now for those who prefer reading :)

Create a new project of C# Project Template. You will find it in Visual C# > Extensibility section.

Projecttemplate

Project will have included Class1.cs file. Feel free to rename it, but make sure you replace the filename in .vstemplate and .csproj
In the sample attached I renamed it to MyObject.
If you open the file you will see that it is a bit different than the class files you usually add to your projects. These values, especially namespace will be changed when you create a new project using this template.
You will notice that there is .ico file included in the ProjectTemplate project. It is an icon that will appear in the project templates list after you install the template and start creating new project. You can replace it with the icon you prefer for you project template.
Project template is now pretty much done.


Now to make it distributable you need to create a new project of VSIX Project type

Projecttemplatevsix

Newly created project will have source.extension.vsixmanifest included which contains main settings for the VSIX package. If you double click it you will get an UI for setting the values, but for fine tuning you will have to switch to XML code view.

The UI consists of 4 sections:

  • Metadata (contains info about the VSIX)
  • Install Targets (list of Visual Studio versions and editions VSIX will be applicable to)
  • Assets (the content of VSIX)
  • Dependencies (libraries VSIX depends on)

Will stick to Assets section for now. One thing you need to include here is the project of C# Project Template type we previously created.
You project template is now ready and after building VSIX project you will have .vsix file created in bin folder of VSIX project.
File .vsix is nothing more than a zip archive, and if you open it with any archive manager like 7zip you will see the content of the package which contains project template as a zip archive inside it.

You can execute VSIX file from bin folder and install the project template now to check if everything is working properly. After installing, if you have any Visual Studio instances running, close them and start Visual Studio again.

Try to create new project and you should be able to see your project type in the list.

Installed1

Usually for your project you will need to reference some custom library.
Reference library can be some library from either

  • Library from GAC (.NET framework library)
  • NuGet.org (nuget package)
  • Local library (3rd party or library developed for that specific project type)

Unfortunately, adding reference to ProjectTemplate project will not neither when VSIX is created nor when it is executed.
Creating GAC references can be done by including them outside of TemplateContent node in the configuration of the .vstemplete file in ProjectTemplate project

    <References>
      <Reference>
        <Assembly>
          System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        </Assembly>
      </Reference>
      <Reference>
        <Assembly>
          System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        </Assembly>
      </Reference>
      <Reference>
        <Assembly>
          System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        </Assembly>
      </Reference>
      <Reference>
        <Assembly>
          System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        </Assembly>
      </Reference>
    </References> 
    

Creating non GAC reference can be done only through NuGet package installer which needs to be invoked from VSIX during installation process.
Either reference is nuget package from nuget.org repository or localy created nuget package, you need to include reference to NuGet wizard to source.extension.vsixmanifest in VSX project.

  <WizardExtension>
    <Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
  </WizardExtension>
    

If we need to reference local assembly, we need to create NuGet package locally first. For that we need to install Nuget Package Explorer first.
For the testing purposes we'll create a class library assembly with an interface which will be implemented in the ProjectTemplate class.

namespace ApplicationBase
{
    public abstract class CustomObject
    {
        private DateTime timeCreated;
        public DateTime TimeCreated
        {
            get
            {
                return timeCreated;
            }
        }

        string instanceGuid;
        public string InstanceGuid
        {
            get
            {
                return instanceGuid;
            }
        }

        string filePath;
        public string FilePath
        {
            get
            {
                return filePath;
            }
        }

        public CustomObject(string filePath)
        {
            this.instanceGuid = Guid.NewGuid().ToString().ToUpper();
            this.timeCreated = DateTime.Now;
            this.filePath = filePath;
        }

    }
}
    

Inherit this class in MyObject class in ProjectTemplate project to make sure that referencing is working after you install template and create new project of it's type.

public class MyObject:ApplicationBase.CustomObject
	{
        public MyObject(string filePath):base(filePath)
        {
            //Custom code implementation
        }
	}
    

For this we'll need a reference to class library. To keep the reference in the project template, we need to create a nuget package using NuGet Package Explorer.

After creating .nupkg create folder packages and store .nupkg file inside it. Change property "Build Action" to True and "Include in VSIX" to True in properties pane. in ProjectTemplate change file .vstemplate file to point to package from VSIX project.
This is important because without setting these values to True, package will not be included in .vsix after compiling

Before installing newly built Project Template extension, you need to uninstall previously installed on from Tools > Extensions and Updates menu option from Visual Studio.

Uninstall

After installing the new VSIX you will be able to create new type of project and you should have all the refernces added to newly created project

  • ApplicationBase
  • System.Configuration
  • System.Xml
  • System.Linq
  • System.Web

For more info and sample chaeckout the article attachment where this whole sample project is available for download

References

  • Share

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.

Comments for this article

comments powered by Disqus