|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionVisual Studio Custom Tools are an excellent feature of the IDE as Chris Sells points out (MSDN). Whenever you create a typed 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:
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:
Registry Template FileWindows 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 Using The CodeThe display for this tool is a simple Windows form with a 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 //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
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||