Writing a custom tool to generate code for Visual Studio .NET

home | snippets | code generation in visual studio .net

Erik Doernenburg and I recently attempted to integrate his C# entity object code generator with Visual Studio. His tool is called Neo (.NET Entity Objects), is on SourceForge, and is worth checking out.

Two Custom Tools (also called Generators) come with VS.NET, MSDataSetGenerator for strongly-typed DataSets, and MSDiscoCodeGenerator for WebService proxy classes. If you have Crystal Reports installed, you'll have some extras too.

Note that most command-line tools mentioned in this article aren't in the default path. Either add the path (e.g. C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin) or start a Visual Studio Command Prompt from the Start menu.

Writing the Generator

Download the COM wrapping code. The library provides a base class BaseCodeGeneratorWithSite from which you should derive your generator. Here's an outline that's ready to go.

using System; using System.Runtime.InteropServices; using CustomToolGenerator; namespace MyProject { [Guid("828BA458-73EF-44E5-B6DA-91ACEC2F38FD")] public class MyGenerator : BaseCodeGeneratorWithSite { public override byte[] GenerateCode(string file, string contents) { string code = "<<generated code>>"; return System.Text.Encoding.ASCII.GetBytes(code); } } }

Some things to note:

Register your Generator for COM interop

Visual Studio will communicate with your custom tool using COM, though you may still write the tool using managed code. Your custom tool assembly must be registered for COM interop.

First, extract a type libarary (.tlb file) using tlbexp.exe

tlbexp MyCustomTool.dll

...this creates MyCustomTool.tlb. Next, register your assembly for COM interop using regasm.exe

regasm /codebase MyCustomTool.dll

If you haven't signed your assembly with a strong name, you'll receive a warning message at this point. Your tool will work either way, though signing does solve other problems. Strong names are managed using sn.exe.

Tell Visual Studio about your Generator

Visual Studio uses the registry to discover custom tools. Using regedit, find the path:

My Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Generators (for Visual Studio 7.0)

My Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\Generators (for Visual Studio 2003)

We can see the following information:

Registry settings

In both cases, multiple Guids exist. Use {FAE04EC1-301F-11d3-BF4B-00C04F79EFBC} for C# projects, and {164B10B9-B200-11D0-8C61-00A0C91E29D5} for VB.NET projects.

You must create a new key, under the appropriate language. The name of this key will be entered for the 'Custom Tool' property for your source file in a Visual Studio project.

The values you need to create are:

If you're creating an installer for your application, these registry settings can be scripted in a .reg file.

Using your Generator

View the properties for your source file (in our case, a Neo schema file). The 'Custom Tool' field should be blank. Enter the name you chose as the registry key name.

Dialog properties

The tool should run automatically. Check to make sure the output was created by opening the Solution Explorer, and enabling 'Show all files'.

Solution explorer dialog

You can force the Generator to execute manually by right-clicking the 'input' file in the Solution Explorer and choosing 'Run Custom Tool'. Output files are tucked away beneath the source file.

If your project is under version control, Visual Studio will attempt to keep the generated file in the repository too.