Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Creating Visual Studio Templates from your Web Projects


:P
On this page:

One of the really nice features of Visual Studio is the ability to very easily create projects templates from existing projects. This is a great feature to create a base project that contains only the things you need or adds additional things that you use in every project or some specific ones. For me this is especially useful for Web Projects as I have a fairly lengthy lists of support files and dependencies that I suck into new Web projects: stock CSS/image folders, scripts, a couple of assembly references and a host of system features and admin pages.

A typical Web startup template for me looks something like this:

TemplateProject

This is basically an extract from a full blown application and pulling out just the reusable components that are a starting point for a new application. Short of the App, ApplicationConfiguration and AppUtils classes which tend to get modified in every application the other files are essentially static and can easily be copied into this ‘template’ project as is by batch file or post build step of a whatever master project that makes up this template.

One thing that you probably want to do with your templates however is change the namespace for source files. So while my application namespace may be something like Westwind.WebToolkitWeb (for the sample app) may be appropriate for the sample app, but in your application most likely the namespace should match your project. You can use a host of template parameters within your project’s text files to replace text when the template is created. The only one that I typically use in a project template is SafeProjectName which looks like this:

namespace $safeprojectname$
{

    /// <summary>
    /// Global Application class that holds various static and
    /// configuration properties and methods. 
    /// 
    /// This class is meant as a one stop application, configuration
    /// constant and management object that unifies various common
    /// applicaiton tasks in one place.
    /// </summary>
    public class App
    {

}
}

When the project is created SafeProjectName is turned into the actual project name with spaces and punctuation stripped which then effectively becomes the base namespace for your project. It’s easy to replace this value with a project wide Replace In Files for (namespace your.namespace with namespace $safeprojectname$).

Note that this step is not necessary. If you are only working internally with generated projects you can probably just use a hardcoded namespace and that’s fine since you’re not likely to have namespace overlap with another Web project. It might make sense though to use something ‘generic’ for the namespace of any components you stick into the template like Westwind.WebApplication or ApplicationRoot or something along those lines.

Exporting the template

Once you’ve set up the template project the way you want it you can export it and this really is the easy part. Find the project in the Solution Tree and then go to File| Export Template:

ExportTemplate

You’ll be asked a couple of questions starting with the type of template to export – choose project:

TemplateWizardStep1

and for the name of the template file and a description. Note you have to pick the project from the projects in the solution – it doesn’t default to the selected project that you exported on which screwed me a couple of times.

The description is what shows up in Visual Studio. I recommend you use a descriptive name in the filename because that’s what the project item will actually use (not as you would expect the description which shows as a tooltip/status notice):

 WizardStep2[4]

Once you do this the template is exported to the location specified, which is just a holding location. When you automatically import the template it is installed into the actual ‘Community Templates’ folder which typically is:

C:\Users\rstrahl\Documents\Visual Studio 2008\Templates\ProjectTemplates

The output from the template generation is a simple .Zip file which contains your project files plus a VS Content file that describes each of the items in the project.

Once installed the template can be used inside of Visual Studio. This puts the template into a generic project location so it shows up in the New Project dialog like this:ProjectDialog1

The project only shows in the generic Visual C# project tree because that’s where the template was actually created. If you go to the Web project types you’ll find that the template doesn’t show up there unfortunately.

To get it to show up in the Web folder you can move the template from the default location to:

C:\Users\rstrahl\Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#\Web

which puts it in the more predictable location.

Since the exported template is simply a .ZIP file you can manually copy the file to this location as well. So if you want to share your template with others just pass them the .Zip file and tell them to install it in the above folder and off they go.

Packaging a Template Project

Having to copy a .Zip file into a specific location is not the easiest of ways to deal with installation especially since Visual Studio default file locations can be changed and so Visual Studio actually includes a packaging mechanism for community components that can copy the files into the right location. The process to do this is pretty simple and involves three steps:

  1. Creating a .vscontent file that describes the template
  2. Zipping up the .vscontent file and your project template .zip file
  3. Renaming the resulting .zip file .vsi

The .vscontent file is simply a descriptive file that holds information about the .zip file with the actual template and it looks something like this:

<VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005">
    <Content>
        <FileName>West Wind West Wind Web Toolkit Web Application.zip</FileName>
        <DisplayName>West Wind West Wind Web Toolkit Web Application</DisplayName>
        <Description>A C# project that contains the base West Wind West Wind Web Toolkit components</Description>
        <FileContentType>VSTemplate</FileContentType>
        <ContentVersion>1.0</ContentVersion>
        <Attributes>
            <Attribute name="ProjectType" value="Visual C#"/>
            <Attribute name="ProjectSubType" value="Web"/>
            <Attribute name="TemplateType" value="Project"/>
        </Attributes>
    </Content>
</VSContent>

Note that here you can also specify where this project template goes. You basically specify that it’s a project template and it goes into the Visual C#/Web folder underneath the templates folder. The project sub type is optional and if leave both the project type and sub type blank the template goes into the default project location just as the default .zip template did.

Once you’ve created this .vscontent file zip it up together with the Project Template.zip file and then rename the resulting .zip file to .vsi.The Explorer pane on the right demonstrates all the files that are used in the process:

ResultingFiles

The West Wind West Wind Web Toolkit Web Application.zip file is the original project template. The .vscontent file of the same name is the content description for the .vsi file. The WestWindWebToolkitProject.zip file is the zipped file of the project .zip and .vscontent file and the WestwindWebToolkitProject.vsi is the final product and self contained project template installer. Note you only need to distribute the .vsi file which contains everything it needs to install the template.

If you double click the .vsi file on any system that has Visual Studio 2008 installed the template installer pops up:

TemplateInstaller

TemplateInstallerComplete

After you run this the template will now be installed in Visual Studio and in the correct location in the Web project section of new items. You can see the final location of the template in the right hand pane of the Explore screen shot above.

Couple of caveats with the .vsi installer. If you for some reason select an invalid template location the installer will fail with a warning that the directory doesn’t exist. It’s crucial that you set up your project with a valid project type that actually exists. If for whatever reason the user has moved the Visual Studio template directories or removed them the installer is not smart enough to create the directory for you which is pretty lame. In that case you have to manually install the template (rename the .vsi file to .zip file, pick out the internal .zip template file and manually copy it to the location). This should be a rare occasion but it actually happened to me first time I tried to install the template because apparently the template directory names have changed between VS 2005 and 2008 and the sample I was looking at used the old names. When in doubt of what the correct names are you can check out other templates in the same folders or in the base VS 2008 installation folders.

Creating the new Project

So now with the template installed we can see it in the right place underneath Web applications and I can create a new project:

NewProjectDialog2

If you follow through with the Wizard you then end up with a new Web project that has all the default files and components installed:

CompletedProject

As you can see all files are there and if you look in the actual code files you also see that the namespaces have been properly replaced.

One Problem: Bin Directory not Copying

Unfortunately there’s one problem with this project: If you have referenced components in the bin directory those references are lost as the bin directory does not copy in the new project template: Here two assembly references in the bin folder are broken:

MissingReferences

Behind the scenes there are two problems: The template exporter fails to export the bin folder altogether. So I figured I can create a custom .vstemplate file and simply add the files in:

 

<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
  <TemplateData>
    <Name>West Wind West Wind Web Toolkit Web Application</Name>
    <Description>West Wind West Wind Web Toolkit Web Application</Description>
    <ProjectType>CSharp</ProjectType>
    <ProjectSubType>
    </ProjectSubType>
    <SortOrder>1000</SortOrder>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>West Wind West Wind Web Toolkit Web Application</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
    <LocationField>Enabled</LocationField>
    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
    <Icon>__TemplateIcon.ico</Icon>
  </TemplateData>
  <TemplateContent>
    <Project TargetFileName="WestWindWebToolkitWebTemplate.csproj" File="WestWindWebToolkitWebTemplate.csproj" ReplaceParameters="true">
      <Folder Name="_Classes" TargetFolderName="_Classes">
        <Folder Name="Application" TargetFolderName="Application">
          <ProjectItem ReplaceParameters="true" TargetFileName="App.cs">App.cs</ProjectItem>
          <ProjectItem ReplaceParameters="true" TargetFileName="ApplicationConfiguration.cs">ApplicationConfiguration.cs</ProjectItem>
          <ProjectItem ReplaceParameters="true" TargetFileName="AppUtils.cs">AppUtils.cs</ProjectItem>
        </Folder>
      </Folder>
      <Folder Name="bin" TargetFolderName="bin">
        <ProjectItem>Westwind.Web.dll</ProjectItem>
        <ProjectItem>Westwind.Web.xml</ProjectItem>
        <ProjectItem>Westwind.Utilities.dll</ProjectItem>
        <ProjectItem>Westwind.Utilities.xml</ProjectItem>
      </Folder>
      <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem>
    </Project>
  </TemplateContent>
</VSTemplate>

and create a custom .zip file to replace the one the auto-export generated that includes the bin folder. But unfortunately that didn’t work either. No bin folder in the target project.

The only way I found to work around this is to add a folder called SupportAssemblies to my project as an included folder and put the support assemblies underneath it. The references then point at these references in SupportAssemblies:

SupportAssemblies

This works, but it’s ugly as hell. The idea would be that the user would move the folder after the project is installed and then reconnect the project references – or more likely – connect to the full project references.

If anybody has a better way to get this done through a project template – even if its manually edited - I’d love to hear it. I think using multiple projects (ie. a Solution template) is the ticket, but this is not something that can be generated by the exporter.

Earlier today I also got a note from Ben Scheirman, who recommended looking at SolutionFactory which has some interesting packaging features that lets you create a solution template rather than a project template. This might be a better way to go as you can then reference assemblies in a sibling folder to the Web Project (like SupportAssemblies). I haven’t had time to check this out more closely but I believe that this should work.

It’s a Wrap

Wrapping up base components into a template project is a nice way to quickly get started with a new application without having to manually assemble and more importantly remember to assemble all the correct components and support files. The basics of the process are straight forward and can be accomplished in just a few minutes. Whether it’s for your own personal reuse or whether you want a more reusable solution for other users of your template it’s a great way to make project startup more efficient.

If you want to play around with this you can check out the West Wind Web Toolkit Web Application Template in the SubVersion Repository as well as the actual projects that the template is based on up the trunk.

Wrap on…

Posted in ASP.NET  Visual Studio  

The Voices of Reason


 

Steve from Pleasant Hill
April 28, 2009

# re: Creating Visual Studio Templates from your Web Projects

Damn fine stuff!

Stephen Inglish
April 28, 2009

# re: Creating Visual Studio Templates from your Web Projects

You can also create a custom wizard for the template that implements IWizard.

public class ApplicationWizard : Microsoft.VisualStudio.TemplateWizard.IWizard 
{
/*  Other IWizard methods not shown here */
private string destinationDirectory;

public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams){
// Retrieve the destination from the replacement dictionary
string destinationDirectory = replacementsDictionary["$destinationdirectory$"];
}

public void RunFinished(){
//Create a directory on the local hard drive to contain the Solution Items
System.IO.Directory.CreateDirectory(destinationDirectory + "\\Solution Items");
// Copy the files from the network share to the local hard drive
File.Copy(@"C:\MyProject\Solution Items\RequiredDll.dll", destinationDirectory + @"\Solution Items\RequiredDll.dll");

// Add a solution Folder for the Solution Items
EnvDTE.Project solutionItemsFolder = mySolution.AddSolutionFolder("Solution Items");

// Add the item from the local hard drive to the project
EnvDTE.ProjectItem addedFile = solutionItemsFolder.ProjectItems.AddFromFile(destinationDirectory + @"\Solution Items\RequiredDll.dll")

// Optionally close the pointless window to clean up the solution from the start
addedFile.DTE.ActiveWindow.Close(vsSaveChanges.vsSaveChangesNo);

}
}

Thomas
April 28, 2009

# re: Creating Visual Studio Templates from your Web Projects

What a post. :-) Trackback from www.oechercoder.net

chris patterson
April 29, 2009

# re: Creating Visual Studio Templates from your Web Projects

Rick,

Nice post. Could be a real time saver.

Brian Lowry
May 06, 2009

# re: Creating Visual Studio Templates from your Web Projects

Is it possible to do all of this for a solution instead of just a project file? I typically have at least two projects for all websites I work on, and I was curious if you knew of a way to do that.

#.think.in
May 15, 2009

# #.think.in infoDose #28 (29th Apr - 8th May)

#.think.in infoDose #28 (29th Apr - 8th May)

Andrew H
July 22, 2009

# re: Creating Visual Studio Templates from your Web Projects

Great post, thanks.

Unfortunately I suspect that the Export Template option is not available in all versions of Visual Studio. I'm using VS2005 Professional (outdated, I know) and it appears not to be available here.

Does anyone have any detail on what versions of VS this is available?

Prasad Anumati
August 29, 2009

# re: Creating Visual Studio Templates from your Web Projects

Please refer below site to enable "Export Template" option:

http://www.codeproject.com/KB/vb/VSNet_Project_Template.aspx

Prasad Anumati
August 29, 2009

# re: Creating Visual Studio Templates from your Web Projects

Hi,

Is it possible to Launch Visual Studio IDE after installation of MSI directly without manual instraction???

Please send me pessi_mca@yahoo.com if it is possible.

Thanks in Advance.

Rgds,
Prasad

Jeffery Seiffert
December 20, 2009

# re: Creating Visual Studio Templates from your Web Projects

If your still having a problem with the bin folder, I setup my template with the following setting and it seams to work okay.

MyTemplate.vstemplate
Added:
<Folder Name="bin" TargetFolderName="bin">
<ProjectItem>PageEventsModule.dll</ProjectItem>
</Folder>


webtemplate.csproj
Addes:
<Content Include="bin\PageEventsModule.dll" />

in an <ItemGroup> that included some other files.

I didn't come up with this totaly on my own.
I read this form link http://forums.asp.net/t/941773.aspx?PageIndex=1 that eventually they figured out that if you want to rename files you need to make the changes in the .csproj file.
I figured that if I included the bin and dll file in the .csproj file that it might work, and it does.

I hope this helps.

Thanks,

JefferyS

Rick Strahl
December 20, 2009

# re: Creating Visual Studio Templates from your Web Projects

@Jeff - actually I figured it out. The easiest way to get private references to work is set up the project with the BIN folder INCLUDED into the project. This will cause the bin folder to install along with all the assemblies and references set to those private assemblies just work. The BIN folder can then be excluded if desired - probably a good idea or else source control will store the bin folder as content.

Aslam
December 22, 2009

# re: Creating Visual Studio Templates from your Web Projects

what a wonderful and gr8 post... tx a lot..

Priyanka Gupta
January 07, 2010

# re: Creating Visual Studio Templates from your Web Projects

hi Rick..great post...really a great help..

i too faced the bin directory issue as the newly added references were not supported in the project templates. so i finally found a solution to overcome this.. we can add new references ,folders to the project where we are exporting project templates. then only the templates.zip folder ends up having the changes..finally when we install the template zip folder ,all the changes are reflected in the template and can easily use the modified template . i have tried this and it really works...

Priyanka Gupta, Impinge Solutions,Mohali
January 07, 2010

# re: Creating Visual Studio Templates from your Web Projects

hi Rick..great post...really a great help..

i too faced the bin directory issue as the newly added references were not supported in the project templates. so i finally found a solution to overcome this..
we can add new references ,folders to the project where we are exporting project templates. then only the templates.zip folder ends up having the changes..finally when we install the template zip folder ,all the changes are reflected in the template and can easily use the modified template . i have tried this and it really works...

Siva
May 31, 2010

# Q: Creating new Visual Studio solution at runtime from existing vs project

I need to create a new visual studio solution at runtime from another visual studio project.

Ex: I created a new windows form appln. I placed a button on that. when i run this, on button click of this project I need to create a new vs solution and Project in some input folder path and add the .vb files which I already have in some folder.
I am not able to know how to create a new VS sln and vs proj at runtime.
Can anybody please let me know how to do it?

regards,
Siva
lovedrawing@gmail.com

Mike Wynn
July 07, 2010

# re: Creating Visual Studio Templates from your Web Projects

Hey Rick,

You mentioned that "The BIN folder can then be excluded if desired " in your last comment above. Do you mean manually exclude in Visual Studio or were you referring to a way to do it in the template itself, some way that is part of the template?

Thanks,

Mike

Mohi
August 30, 2010

# re: Creating Visual Studio Templates from your Web Projects

Thanks for the Post.. it was Good.

but these are just the basic Steps you Did. If you have any .vstemplate file how do you convert that .vstemplate file to your project without doing the export template feature.

Suppose you need to create a Project Template with a Wizard. Wizard has radio buttons Project 1, project 2, Project 3, Project 4 and a finish button. when you hit the any radio button I need to create a specific project.

My Solution structure would contain one Class Library Project for implementing the IWIzard Interface, Project Template Project root .vstemplate file will contain the <ProjectTemplateLink> attribute for the location of the .vstemplate files for each of the projects.

Can you help me out Please..

rohini
December 21, 2010

# re: Creating Visual Studio Templates from your Web Projects

Thanks its a great post. I am trying it. but I want to do some more.
I want to show my own wizard by which I choose database for project and that connection string gets aadedd in web config file. for that I create one class library and that implements Iwizard class. then I just added that reference into that project.
make some modifications into vstemplate file add tab wizard extension .
but anyhow that wizard couldn't open
whats the resond?
could you help?

Paul
March 14, 2011

# re: Creating Visual Studio Templates from your Web Projects

I followd the instructions but when I go to create my new project from the template, all it shows is the "Name" box, the "Location" box for the new project is not shown. Nor is the Create Directory for Solution nor the Add to source control checkboxes listed.

What did I do wrong?

Bill
February 13, 2020

# re: Creating Visual Studio Templates from your Web Projects

I know this is an old post, but I found it in 2020 trying to solve it. And it looks like you can actually do what you want.. just need one more step..

So modify the *.vstemplate file like you did to include the missing dll's...

  <Folder Name="bin" TargetFolderName="bin">
    <ProjectItem ReplaceParameters="false" TargetFileName="myMissingReference.dll">myMissingReference.dll</ProjectItem>
</Folder>

but in addition, also manually edit the template's *.csproj file. In there you will find several "Item Groups"... Either add a new one, or just add on your file(s) to an existing one that seems to be related like so...

<None Include="bin\myMissingReference.dll" />

Now, when you create a new Project based off your template.. you will get the bin folder with your missing dll's already there.


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024