Creating custom project template with wizard for Visual Studio

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg This

Introduction
If you are a experienced .Net developer, you might have already created or used custom project template in Visual Studio. In new versions of Visual Studio, Microsoft has included common files like jQuery, CSS, standard Master page etc. in the default web site template which was not there in old Visual Studio versions.

I always require jQuery file, standard CSS file of client, some common logo images to be added in my new projects. Also, whenever I creat a new project, I require to modify the connection string by going to web.config file. There are also some other common setting which I repetatively do in web.config.

Visual Studio provides some easy way of creating a cusomt project template so that, such a common items and code can be included in the new project template.

In this short article, I will explain about

Creating project template
Creating DLL for new project wizard dialogue
Incorporating new wizard in project template to accept additional input from user
Using project template to create new website
Article Body
Note that, I am using web site project as a example in complete article. However, this is applicable for web application or any other project (including console application, WinForm application etc.)

Lets first start by creating simple project template which will contain common files that we require in most of our projects. You might be aware that, Visual Studio provide a option of exporting existing open project as temaplate. You can simply open a web site project and then go to File -> Export Temaplate and then follow the wizard stepas this will make current project as a template which can be used as a base while opening new project next time.

However, to have more control over templated items and to use separate wizard dialouge etc. we can follow steps given below (Which is the focus of the article)

Creating simple project template first

Suppose, I want that jQuery file be added by default when I creat new project (This is already there in Visual Studio 2010 but not in VS 2005) also, there is a standard CSS file and a image file which should be included. Also, there is public function class file which I want to use across all my projects.

Lets first creat new web site project and add all these files into this project.

Now, add new XML file in the root directory of project and name it as ProjectTemplate.vstemplate. This is the file which will contains information required to create new project in VS. The content of .vsTemplate file are diaplayed below (note that you could name the file as per your choice)

?123456789101112131415161718192021222324252627282930 Blue Lemon Default Project TemplateA web site project template by Kedarlemon.icoWebCSharpWebSitepubClass.csjquery-1.4.1.jsjquery-1.4.1.min.jsMyJS.jsStandardTheme.csslemon.icoDefault.aspx

Default.aspx.

csweb.config
The purpose of various tags inside in above XML format is evident from their name. You can change these values as per your choice (like ProjectType could be either CSharp/VisualBasic/JSharp/Web so that project template can be categorized into appropriate type).

Insidetag, I have includedtag and specified name of .ico file. The Icon tag information is used to display picture of project template while creating new project. I strongly advice to read this to know more about template data.

Intag, we need to mention details of all files which we wish to include in the template. Creat structre of all necessary file by usingto mention folder name (like App_Code) and usetag to give file details. As name suggest by setting OpenInEditor=”true” in ProjectItem tag, the respective file can be set to be opened by default when you start a new project by selecting this template. There is another attribute of ProjectItem as ReplaceParameters. This can be set to true so that dyamic paramters can be added into the file and used by template when creating new project.

To see its use, open pubClass.cs file from App_Code and change its namespace value as $safeprojectname$. The content of class file looks as

?1234567891011121314151617181920 using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace $safeprojectname$ { ///
/// Summary description for Class1 ///

public class PubClass { public void ExecuteQuery() { } } }
The parameter $safeprojectname$ in above code has certain meaning in Visual Studio project template. VS provides name entered by user in New project dialogue in this parameter. By setting ReplaceParameter to True for pubClass.cs file in XML file above, we have intimated VS to replace $safeprojectname$ in pubClass.cs with new project name enterd by user.

In above XML format, there is a tag as. Although, Web site project does not have any solution or project file, it is required for interanl purpose. Hence, go to folder location where you have defined this project and create new blank file and name it as WebApplication.webproj.

After refreshing project in Visual Studio, below is list of files available.

If you want just to create simple projetc template without any additional dialogue and just default set of files. Then you can jump to third section (However, I would suggest to read on next section)

Creating DLL for new Project wizard dialogue

Until this it is fine. But what if I want that when I create a new project using custom template it should ask me for connectionstring setting I want to add in my web.config file? so that I dont have open web.config file and add connection string value again after project is started.

Project template wizard could come handy in such situations. However, it is not straightforward as creating project template. To add wizard form in project template, we have to create a separate class library project and follow below steps.

Create new class library project and add a windows form in it with required wizard design

Right click on project in solution explorer and select windows form. name it as wizardForm.cs and create form design (in this case, I want to let use to enter connection string and some other custom message)

In the wizardForm.cs c# code, create public properties to return value of form fields. The complete code is

?1using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CustomOptions { public partial class wizardForm : Form { public string strCustomMessage; public string strConnectionstring; public wizardForm() { InitializeComponent(); } public string get_CustomMessage() { return strCustomMessage; } public string get_ConnectionString() { return strConnectionstring; } private void btnAdd_Click(object sender, EventArgs e) { strCustomMessage = txtParameter.Text; strConnectionstring = txtConnectionstring.Text; this.Dispose(); } } }
Update class file to create wizard template assembly

Now is the time to update class file of to create project template assembly. Before that, it is required that we add reference to following assemblies in the project

Right click on project -> select Add reference. In .Net tab select Microsoft.VisualStudio.TemplateWizardInterface, System.Windows.Forms and EnvDTE. In the class.cs file (or you might have different name to this file) add using statement to these namespace (in case of vb.net, it is import).

We required to create a class which inherits form IWizard interface. IWizard has many other functions out of which we are going to provide implementation for RunStarted and RunFinished.

?using System; using System.Collections.Generic; using Microsoft.VisualStudio.TemplateWizard; using System.Windows.Forms; using EnvDTE; namespace CustomOptions { public class WizardClass : IWizard { private wizardForm wizardFrm; private string customMessage; private string strConnectionstring; public void BeforeOpeningFile(ProjectItem projectItem) { } public void ProjectFinishedGenerating(Project project) { } public void ProjectItemFinishedGenerating(ProjectItem projectItem) { } public void RunFinished() { MessageBox.Show(“The custom options has been added. Creating new project with selected template and parameters”); } public void RunStarted(object automationObject, DictionaryreplacementsDictionary, WizardRunKind runKind, object[] customParams) { try { //Call win form created in the project to accept user input wizardFrm = new wizardForm(); wizardFrm.ShowDialog(); //call property from wizardForm to read user input values customMessage = wizardFrm.get_CustomMessage(); strConnectionstring = wizardFrm.get_ConnectionString(); // Add custom parameters. replacementsDictionary.Add(“$custommessage$”, customMessage); replacementsDictionary.Add(“$connectionstring$”, strConnectionstring); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } public bool ShouldAddProjectItem(string filePath) { return true; } } }
Note carefully that, all we are doing in RunStarted method is displaying wizard dialogue, reading values entered by user in wizard form and add it in dictionary variable. We are also adding a string enclosed in $. This works as a key which we would use later in project template to read user inputted value and replace in template pages.

Sign assembly and add in GAC

We have now completed creating wizard form. To use it in project template, the assembly needs to signed with strong name and be added in GAC. To sign assembly, right click project go to Properties in project properties page go to Signing tab -> check “sign the assembly” checkbox. In “Choose string name key file”, select New. Then in new dialogue, enter Key file and password/s the key file (.pfx) would be generated in root of project.

This assembly now needs to be added in GAC (global assembly cache) you might already know how to do it or read this.

Incorporating new wizard in project template to accept additional input from user

We now have a custom project template and a template wizard assembly. Now go back to our original project template (step 1 above). In the .vsTemplate XML file, we have to add reference to the assembly we just created. To do that, add following tags after closingtag

?123456 wizardTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0abc167b5bd11206 CustomOptions.WizardClass
Note that, we need assembly information for this. To get assembly information of just added assembly, go to Visual studio command prompt and type

> gacutil -l

this will give us the assembly information string which we can copy and paste intotag above. Also note that, FullClassName tag should indicate namespace.classname of wizard project.

If you see complete XML format of .vsTemplate file, we had set ReplaceParameter to true for web.config as well as default.aspx. That is because, the we are going to replace values in these files with string entered by user in wizard form.

Go to web.config file of project template add replace connectionstring tag as

?12345
The $connectionstring$ indicate that value of $connectionstring$ parameter should be replace here. One final thing we are left with is to package the template project. To do this, go to folder location where template project is saved. in the root directory, select all files -> right click -> send to -> Compressed (zipped) Folder.

We now need to add this zip file into default template location of visual studio. Mostly (unless you have changed) VS template stored at

\My Documents\Visual Studio 2010\Templates\ProjectTemplates\\

or

\My Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual Web Developer

Read this to know how can you find default location of project template on your machine. Once the default location is identified, copy and paste the zip file here and that’s it!

Using project template to create new website

To test the project template with wizard, open new Visual studio instance and go to File -> New web site. The new project name can be seen here

Select this new project template and click OK. A dialgue will appear as this. Add values in the textboxes

Then click on Add button. The project will start with all default files selected by us as part of template. Go to web.config file now. whoo! instead of $connectionstring$ you can now see value entered by us in project wizard dialogue.

Conclusion
Diffrent functionality of Visual Studio can be extended very easily. By creating custom wizard in project template we can do lot of many other things to speed up development process. With NuGet, it is more easier to use any existing project templates.

If you know of any NuGet package which takes care of creating project template wizard then please update us.

Thanks for visiting my site. Your comments are welcome :)

website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india

Obtaining Image Information on your own

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg This

With help from the .NET Framework, everybody can program his own ImageInfo component without this project turning into an inordinate effort – you just have to use the Bitmap class to your advantage. And presto – we have size information for many more image file formats!

Creating the ImageInfo Component

I have choosen to encapsulate the functionality of obtaining image information in its own class. This class has the following methods and properties:

  • void Load(string): Loads the image file specified.
  • [get] int Width: Reads the image width.
  • [get] int Height: Reads the image height.
  • [get] string Format: Reads the image format (“JPEG”, etc).

The Properties obviously are read-only properties implemented with the help of accessors. For reasons of lazyness, the class does not catch any exceptions, but passes them through to the caller (file does not exist, invalid format, …).

The complete source code looks as follows (ImageInfo.cs):

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace AspHeute
{
 public class ImageInfo
 {
   Bitmap m_bmpRepresentation;

   public void Load(string strImageFile)
   {
    m_bmpRepresentation = new Bitmap(strImageFile, false);
   }

   public int Height
   {
     get { return m_bmpRepresentation.Height; }
   }

   public int Width
   {
     get { return m_bmpRepresentation.Height; }
   }  

   public string Format
   {
     get
     {
      ImageFormat bmpFormat = m_bmpRepresentation.RawFormat;
      string strFormat = "unidentified format";

	  if (bmpFormat.Equals(ImageFormat.Bmp)) strFormat = "BMP";
	  else if (bmpFormat.Equals(ImageFormat.Emf)) strFormat = "EMF";
	  else if (bmpFormat.Equals(ImageFormat.Exif)) strFormat = "EXIF";
	  else if (bmpFormat.Equals(ImageFormat.Gif)) strFormat = "GIF";
	  else if (bmpFormat.Equals(ImageFormat.Icon)) strFormat = "Icon";
	  else if (bmpFormat.Equals(ImageFormat.Jpeg)) strFormat = "JPEG";
	  else if (bmpFormat.Equals(ImageFormat.MemoryBmp)) strFormat = "MemoryBMP";
	  else if (bmpFormat.Equals(ImageFormat.Png)) strFormat = "PNG";
	  else if (bmpFormat.Equals(ImageFormat.Tiff)) strFormat = "TIFF";
	  else if (bmpFormat.Equals(ImageFormat.Wmf)) strFormat = "WMF";

      return strFormat;
     }
   }
 }
}

The majority of the code is to be found in the accessor for the image format (Format), as the image format is defined as GUID and I therefore have to perform all comparisons with Equals. The user however receives a simple-to-use String, e.g. for a Select Case in VB.NET.

Loading the bitmap is done using the constructor of the Bitmap class in the Load method. From this time on, the complete bitmap is in memory. As memory is managed in .NET by means of the garbage collector, the Bitmap class and the ImageInfo object should be removed explicitly (=on your own) from memory using a Dispose method I did not build in (left as an exercise for the reader):

public void Dispose()
{
  m_bmpRepresentation.Dispose();
}

This method should be called after the last use of the ImageInfo class which will significantly improve performance of the application. In general the rule under .NET is that resources should be freed explicitly as soon as possible! Waiting for the garbage collector can turn into a (performance) trap.

The component is compiled using the compile.bat batch file contained in the download. After compilation, the component has to be copied to the bin directory of the Web site and can then be used in all ASP.NET pages.

Using the Component

As the component does not exactly offer “a lot” of functionality, use is conceivably simple. The only important point is handling errors – as I left exception handling out of the component this has to be done in the ASP.NET file (demo.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="AspHeute" %>
<%
string strImageFile = Page.MapPath("myImage.jpg");
bool bLoadedOK = true;
ImageInfo imgInfo = new ImageInfo();

try
{
  imgInfo.Load(strImageFile);
}
catch (Exception e)
{
  Response.Write(e.ToString());
  bLoadedOK = false;
}

if (bLoadedOK)
{
  Response.Write("Width: " + imgInfo.Width + "<br>");
  Response.Write("Height: " + imgInfo.Height + "<br>");
  Response.Write("Image format: " + imgInfo.Format + "<br>");
}
%>

As for this source code, everything should be quite clear. You are cordially invited to try various image files and formats!

Conclusion

And yet again .NET saves the day by supplying enormously much functionality for free – we just have to look for it. And the best part is that today’s component can be used in all .NET Applications not just ASP.NET Pages.

Downloading the Code

Click here, to start the download.

website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india
website designing delhi,website designing india,website designing,website design,websitedesignin.org,seo,search engine optimization,seo articels,website design delhi,website design india