Click here to Skip to main content
14,297,259 members

How to Create Your own Visual Studio Wizard

Rate this:
3.43 (5 votes)
Please Sign up or sign in to vote.
3.43 (5 votes)
22 Aug 2006CPOL
This article describes a process creating VS wizard.

Introduction

This topic describes how to write simple New project wizard for Visual Studio, that will generate some data, such as code file, and attach it to the project.

Part One: Coding

Hello! Today we'll learn, how to create your own wizard, that will do some work for us and instead of us. Sounds good, isn't it?

First of all, I must say, that this wizard will be for VS 2005. So start it and create new Class Library Project. In generated project (it's generating from template, we'll speak about them later) open file Class1.cs (you may rename it) and erase every line of code in it, because we'll do everything with our own hands.

References

First we must specify "using" part. We'll use these namespaces:

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.VisualStudio.TemplateWizard;
using EnvDTE;

 

You may notice some unfamiliar names. Last two are namespaces for VS 2005 developer team, so for little time we may feel ourself as IDE creators. Well, if we want to use these cool namespaces we must add proper references which have same names (Microsoft.VisualStudio.TemplateWizard and EnvDTE).

Main Class

As soon as we have "using" part, we must create namespace and class in it. Let's do it – namespace must be the same as the default namespace of your solution (you may see it in solution properties). Class may have any name that you wish and what is most important: it must be inherited from the IWizard interface, which will provide us needed wizard logic. For example:

namespace SampleWizard
{
    public class WizardClass : IWizard
    {
    }
}

Implementing

Well, for now it will be great to implement methods of IWizard. Let's do this:

// This method is called before opening any item that 
// has the OpenInEditor attribute.
public void BeforeOpeningFile(ProjectItem projectItem) 
{
}

public void ProjectFinishedGenerating(Project project) 
{
}

// This method is only called for item templates,
// not for project templates.
public void ProjectItemFinishedGenerating(ProjectItem projectItem) 
{
}

// This method is called after the project is created.
public void RunFinished() 
{
}

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

// This method is only called for item templates,
// not for project templates.
public bool ShouldAddProjectItem(string filePath) 
{
    return true;
} 

As we can see IWizard provides us various ways to manage creating project. For us important only these methods: RunStarted and ProjectFinishedGenerating. Later, I think, you could add some additional code, that answers your needs.

 

User Interface

Let's find out our two methods closer. RunStarted starts when VS finishing generating new project according to its template, so this is the main entry point for our wizard. Parameters of the method are:

  • automationObject – may be casted as DTE
  • replacementsDictionary – contains reserved words for template, that will be replaced with the values of the dictionary. Also, you may add your own in format %word%. More information in MSDN
  • runKind – specify run kind of the wizard
  • customParams – custom params

 

Well, this method will be main for us. Next question is: how we imagine interface of our wizards. By the way, it may be invisible at all. For example, in this method we can only change project name by adding word "My" (using replacementsDictionary) at the beginning or something else. But in our case, we'll make a little bit more and add user interface to wizard. It's very easy. Just add new form in the solution. Let's call it UserInputForm. Also let's place some controls on it, like textbox, label, button and any other stuff that you want. Our wizard will automatically add to project code file with generated empty class. So call textbox tbName, set label text to: "Enter name of new class" and make button an AcceptButton of the form, also set it text to OK.

In the code of form create new string property named ClassName and in get-section write:

return tbName.Text;

Next we must override the OnClosing event and write:

if (ClassName == "")
    return;
base.OnClosing(e);

 

Well, I think it will be enough for our training sample. Let's go back to our WizardClass and write at the beginning:

private <code>UserInputForm newForm;

Then go to RunStarted method and type:

newForm = new <code>UserInputForm();
newForm.ShowDialog();

Project Management

As you understand this will show our dialog as soon Visual studio will create new project. In this dialog user assumed to enter the name of new class, that we'll create in new file and add to the project. So next we want get an event where we can add some stuff to project. This is ProjectFinishedGenerating method. Here we'll create new code using data from Input form, write this code to the file and attach file to the project. Something like this:

string dir = Path.GetDirectoryName(project.FullName);
string code = 
    <code>"using System;\nusing System.Collections.Generic;\nusing System.Text;\n\n" +
    "namespace WizardGenerated\n{\n\r\tpublic class " + 
    newForm.ClassName + "\n\r\t{\n\r\t}\n}";
StreamWriter sw = new StreamWriter(dir + "\\" + newForm.ClassName + ".cs");
sw.Write(code);
sw.Close();
project.ProjectItems.AddFromFile(dir + "\\" + newForm.ClassName + ".cs");

 

I think everything is pretty clear. We just writing to the string template of new code file with the user-defined class name. Then we write it to the disk and add new project item from file.

Part Two: Installing

Congratulations!

If you have reached this section it means, that you already have created your own wizard. Just build the project and the dll with the wizard will appear.

But what we can do with this library? Well, installing of the wizard it's also difficult thing. First, you must add you assembly (eq. dll) to the GAC (General assembly cache). To do that, you must have a strong name for assembly and to do this you must sign your assembly. Sounds scaring? To battle!

Signing

Signing is very easy thing in VS 2005, because its developers add special button to the properties of the project and saved us from boring console stuff. So, go to the properties page of you project and switch to the Signing tab. Check "Sign the assembly" box and in the combo-box create new key file. That's all.

Adding to GAC

Next, we must add assembly to GAC. Very easy: just run SDK Command Prompt from your Start\Programs\Microsoft .NET Framework SDK v2.0. In appeared command window type: gacutil -i "<path to your compiled dll here>". This will install your dll to assembly cache and allow you to reference on it in templates. Also we must know token of assembly key. There is two ways to find it. First is to type in same command window: gacutil –l >> "some path to file here". This lists all installed assemblies with their properties including token to specified file. Using this way, you may also make sure, that assembly really was added to GAC. Simply find it by the name in the list and save it's token somewhere. It must be in hexadecimal form, something like: 2ee9fb161af32259. Other way to find token is to use sn.exe tool from same FW 2.0 SDK. In the Command Prompt type: sn -T "<path to dll here>". This command will show you a token of assembly.

Into the Template

So, now you have assembly, installed in the cache, and its token in the hands. It's time to add reference of the wizard to some template. You can create your own template, but this time we'll use one of default Visual Studio templates. Go to the MyDocuments directory and find there folder named Visual Studio 2005\Templates\ProjectTemplates\Visual C#. You can see there a list of zip files. This is archived templates of the projects. Unzip Console.zip and open MyTemplate.vstemplate file. We can see simple xml file. After the "template content" node we must add these lines:

<WizardExtension>
    <Assembly>SampleWizard, Version=1.0.0.0, Culture=neutral, 
        PublicKeyToken=2ee9fb161af32259, Custom=null</Assembly>
    <FullClassName>SampleWizard.WizardClass</FullClassName>
</WizardExtension>

Of course your values and names may be different. After saving this document just zip the folder back, and restart studio. If everything was done clear, when you'll try to create new console project our dialog form will appear and after closing wizard dialog code file will be added to project.

 

Restore Everything

If you want undo this things, just return template archive to it's original state and uninstall dll from GAC using gacutil with –u key. If you want to make some changes to wizard you must rebuild it, uninstall it from GAC and install again

Finally

So, for now you know how automatize some work that you do too often. Hope you'll enjoy this feature and find it useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

A$TRAL Moristar
Web Developer
Ukraine Ukraine
Hi! My name is Petrusenko Alexander. I was born in Ukraine in the city of Donetsk and still I'm here. I am C++/C# programer and by now I'm taking part in developing Access Control System. Well, that's all.
Hail from Ukrane!!!

Comments and Discussions

 
QuestionSolution or Project Classes on Wizard's Combobox Pin
Henrique Clausing20-Aug-14 9:21
memberHenrique Clausing20-Aug-14 9:21 
GeneralError while creating Projects in other system Pin
Kavitha Sathishkumar11-Nov-07 22:48
memberKavitha Sathishkumar11-Nov-07 22:48 
QuestionStrange Issues Pin
mustafashabib6-Jul-07 9:20
membermustafashabib6-Jul-07 9:20 
Questionzip files not created Pin
kartheek nagasuri14-Jun-07 21:00
memberkartheek nagasuri14-Jun-07 21:00 
GeneralWorking example Pin
Rudolf Jan6-Jan-07 9:27
memberRudolf Jan6-Jan-07 9:27 
GeneralA UserControl Wizard... Pin
naroqueen14-Sep-06 20:41
membernaroqueen14-Sep-06 20:41 
GeneralRe: A UserControl Wizard... Pin
A$TRAL Moristar14-Sep-06 21:44
memberA$TRAL Moristar14-Sep-06 21:44 
GeneralRe: A UserControl Wizard... Pin
A$TRAL Moristar14-Sep-06 21:59
memberA$TRAL Moristar14-Sep-06 21:59 
GeneralRe: A UserControl Wizard... Pin
David Hay15-Apr-07 15:03
memberDavid Hay15-Apr-07 15:03 
GeneralSorry Pin
naroqueen14-Sep-06 8:03
membernaroqueen14-Sep-06 8:03 
Generalinvalid token Pin
naroqueen14-Sep-06 7:49
membernaroqueen14-Sep-06 7:49 
GeneralIt doesn't work in VS# 2005 Express Pin
ubivetz22-Aug-06 4:01
memberubivetz22-Aug-06 4:01 
GeneralRe: It doesn't work in VS# 2005 Express Pin
Ed.Poore22-Aug-06 4:11
memberEd.Poore22-Aug-06 4:11 
GeneralRe: It doesn't work in VS# 2005 Express Pin
A$TRAL Moristar22-Aug-06 4:35
memberA$TRAL Moristar22-Aug-06 4:35 
GeneralRe: It doesn't work in VS# 2005 Express [modified] Pin
ubivetz22-Aug-06 5:07
memberubivetz22-Aug-06 5:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 22 Aug 2006

Stats

81.7K views
29 bookmarked