Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automated Registration of Visual Studio Custom Tools

0.00/5 (No votes)
2 Jun 2004 2  
Describes a utility to simplify the registration of a VS.NET custom tool.

Sample Image - screenshot.jpg

Introduction

Visual Studio Custom Tools are an excellent feature of the IDE as Chris Sells points out (MSDN). Whenever you create a typed DataSet from an XSD, you're using the Microsoft custom tool code generator MSDataSetGenerator. Having written several Visual Studio Custom Tool Code Generators (articles to follow), I was looking for an easy way to register them both for the COM interop necessary as well as make the registry entry needed for Visual Studio. I also wanted to be able to perform this registration seamlessly in an installer package. This utility is the result.

By using a simple XML template or command line arguments, this executable will register the code generator for COM as well as a custom tool. You only need to supply 4 pieces of information:

  1. The name of the Assembly you are going to register.
  2. The name you want to use for your custom tool.
  3. The class ID GUID for the custom tool.
  4. Descriptive text to be put in the registry to describe your tool.

Given this, the registration tool will present you with a window of the current activity and its status.

XML Template

<?xml version="1.0" encoding="utf-8" ?>
<dotNetRegistration 
       xmlns="http://schemas.mckechney.com/DotNetRegistrationConfig.xsd">
    <dllName>SimpleDataClassVSGenerator.dll</dllName>
    <customToolName>SimpleDataClassGenerator</customToolName>
    <guid>{34EAC568-72B1-439e-BE3F-C1D0ADF50CE9}</guid>
    <prodDesc>Simple DataClass Generator by Michael McKechney</prodDesc>
</dotNetRegistration>

This is an example of a template file I've used to register a Custom Tool I wrote. By default, the app looks for a file named DotNetRegistrationConfig.xml, but you can specify a different name via a command line argument. It's fairly straightforward with the following definition:

  • dllName - the name of the assembly to register (in its current version, the application assumes that the assembly is in the same directory as itself. Since this is usually run as an install package custom action, I haven't seen the need to change it).
  • customToolName - what the end user will type into "Custom Tool" property of the project file.
  • guid - the class ID GUID that you've assigned the generator (this is how the VS.NET registry entry finds the DLL).
  • prodDesc - how the custom tool will be described in the VS.NET registry.

Registry Template File

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\ 
  7.1\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\<<G

eneratorName>>]
"CLSID"="<<guid>>"
"GeneratesDesignTimeSource"=dword:00000001
@="<<DefaultKeyValue>>"

This file (DotNetRegistration.reg, which should also be in the same directory as the executable) acts as the registry template for the custom tool. The items in double brackets are replaced with the XML values as it is processed. A couple of things to note: The 7.1 value specifies that this will be registered as a custom tool for Visual Studio .NET 2003. You'd want to change that for different versions. Second the GUID value {FAE04EC1-301F-11D3-BF4B-00C04F79EFBC} is for a C# code generator. If you look at the Generators key, you'll find several different GUIDs representing different languages. If you want to register a code generator for another language, you'll need to change this value.

Using The Code

The display for this tool is a simple Windows form with a ListView, so I won't go into detail for that. All of the real action takes place in the CompleteRegistration method. Using some reflection and RunTime methods, I first retrieve the running directory,

string full = System.Reflection.Assembly.GetExecutingAssembly().Location;

and the root directory for the .NET runtime being used:

string dotNetRoot = 
  System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();

Next, I make sure everything is where it's supposed to be and fail if they're not:

if(!File.Exists(dotNetRoot + "regasm.exe"))
{
    MakeListEntry("Unable to locate regasm.exe",false,true);
    Thread.Sleep(new TimeSpan(0,0,5));
    throw new ApplicationException("Install Failed");
}

//Make sure the Assembly to register is present and accounted for

if(!File.Exists(currentDir+dllName))
{
    MakeListEntry("Unable to locate "+currentDir+dllName,false,true);
    MakeListEntry("** Installation Failed **",true,true);
    MessageBox.Show(currentDir+dllName);
    Thread.Sleep(new TimeSpan(0,0,5));
    throw new ApplicationException("Install Failed");

}

Then, using the System.Diagnostics.Process class, I begin to run through the registration steps:

//Register the Type library for the Assembly

prc.StartInfo.FileName = dotNetRoot + "regasm.exe";
prc.StartInfo.Arguments = "/tlb \""+ currentDir+dllName+"\"";
prc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
prc.StartInfo.WorkingDirectory = dir;
prc.Start();
prc.WaitForExit();

//etc...

After each step succeeds or fails, the ListView is updated with its status. Once complete, the window closes and returns a status code 0 for success, 100 for a failure. If successful, your Custom Tool is ready for use! As I prepare my article on code generation, you'll get to see how I've used this tool in installer packages as a custom action for a seamless installation of a custom tool code generator.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here