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:

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:

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

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):

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:

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:

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:

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:

Creating a .vscontent file that describes the template

Zipping up the .vscontent file and your project template .zip file

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:

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:

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:

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:

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:

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:

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:

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:

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.

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.

@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.

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...

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...

Therefore you have worked hard in making your web site, often adding substance to it, and building links and increasing search engine placements. The following step, that many fail to notice, is to capture your guests by utilizing an automatic responder. If you would like to avoid all the problems associated with setting up your websites online then read my LPGen2 review for more information.

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?

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?

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.

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?

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.