I’ve spent a part of the last two days cursing the managed project framework (it’s a bliss, too, and I’m thankful that it’s available at the same time), because it is too different from what I need, and I’ll probably end up rewriting most of it to use different approaches and not use _MSBuild _anymore.

I’ve spent more time, however, on reading up on Debug Engines in Visual Studio 2008 and I’ve started work on my own yesterday. To be honest, I haven’t really started to work on it, I’ve rather spent the evening and most of today figuring out how to register a debug engine at all and write attributes for that, so that it becomes an automated process, just like it’s done for Packages and Language Services by using attributes like ProvidePackage and ProvideLanguageService.

The code has turned out pretty nicely and now you can use the attributes like this, for example, to register a debug engine:

    [ProvideDebugEngine("{5887F58F-3B7F-401d-95CE-A7BADA1E4D7D}", "TorqueScript Debug Engine",
        Attach = true, ProgramProvider = typeof(VSTorqueScript_DebugEngine))]
    [ProvideIncompatibleEngineInfo( "{5887F58F-3B7F-401d-95CE-A7BADA1E4D7A}" )]
    [ProvideIncompatibleEngineInfo( "{5887F58F-3B7F-401d-95CE-A7BADA1E4D7F}" )]
    [ProvideAutoSelectIncompatibleEngineInfo( "{5887F58F-3B7F-401d-95CE-A7BADA1E4D7F}" )]
    [ProvideObject(VSTorqueScript_DebugEngine)
    [Guid(GuidList.guidVSTorqueScript_DebugEngineString)]
    public sealed class VSTorqueScript_DebugEngine
...

In my opinion this looks pretty neat - and it works.. / I really love the whole concept of attributes and the way they make coding a lot easier (even though it’s hard to find information about useful attributes, as you only find out they exist when you stumble over them or write them on your own).

You can find the code here: http://www.icculus.org/~black/weblog/VS_DebugEngine/

A few notes:

  • The implementation was done making heavy use of copy&paste and quick replace (I copied the table containing the help description of the metrics into the source file and reworked it using RE magic to look the way it does now)
  • At first I used Type.GetProperties to enumerate all properties and write them out into the registry but that bloated the resulting registry entry, of course. Because of this I later switched to the HashTable approach that I first found in SDK’s implementation of ProvideLanguageServiceAttribute.
  • The restriction that all attribute parameters must be constant expressions forced me to make a few changes - at first I had Guid properties and for the incompatible engines list I expected a Guid[], which didn’t work. I changed the Guids to Strings and added the Provide*EngineInfo attributes instead of the incompatible engines list (same for the autoselect one, of course).
  • The Provide*EngineInfo attributes contained their registry code at first. This was ugly because they kind of required a ProvideDebugEngine attribute to exist, too, which I couldn’t enforce. Later I changed them to be pure value holders and moved all registry code into ProvideDebugEngine.

Now nothing happens if you don’t supply a ProvideDebugEngine attribute, too.

Now I’ll try to start to work on the actual Debug Engine for TorqueScript.

Cheers,
 Andreas