Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

Visual Studio Integration

Visual Studio 2005 doesn’t just come with ‘edit-and-continue’. Hidden away is a little gem called ‘Extensibility’.
Dermot Hogan starts to mine the motherlode…

 

In this new series, Dermot explains how to integrate a programming language into Visual Studio 2005. Part One: The Basics (see also: Part Two)

Microsoft isn’t shy about advertising its merits. Not usually, anyway. But it’s made an exception for one part of Visual Studio. You’d be hard pressed to find much of a mention of this in the press, but you can now customise and extend Visual Studio 2005 to a far greater extent than before. I don’t mean the usual ‘automation’ stuff, called from a Visual Basic for Applications (VBA) script, either. What we’re talking about are full blown programmatic extensions to Visual Studio. You can get Visual Studio to host a Cobol environment, an Oracle PL/SQL development system or an implementation of your favourite ‘ology’ – complete with boxes and interconnecting squiggles.

There are three ways to extend Visual Studio:

  • First, there’s the simple macro approach. You record a few keystrokes and attach them to a key. Press the key and your key sequences are repeated. It’s simple, easy to do and use but limited in its scope.
  • Second, there’s the ‘automation’ model. Like Office, Visual Studio has a COM model which can be called from a scripting language such as VBA. You can access most of the document/code windows in Visual Studio and do quite a lot of neat stuff with automation. The problem is that it’s still an add-on. You can’t fundamentally override the way the debugger works for example.
  • The third way is by far the most interesting. It’s Visual Studio Extensibility or Visual Studio Industry Partners (VSIP).

As usual with Microsoft, the names seem a little confused. ‘Extensibility’ can refer to the whole thing – macros, automation and the VSIP program - or just the VSIP bit. And VSIP refers to ‘Industry Partners’ or ‘Integration Package’. Whatever its name, to get at the most interesting bits, you have to download the Visual Studio SDK. And to get this you have to register with Microsoft as an ‘Affiliate’ (start here: http://msdn.microsoft.com/vstudio/partners). It’s free, relatively painless and at the end of the registration, you can down load the VSIP SDK - about 85MB in size.

Just in passing, I’d note that the Industry Partners thing has been around at least since Visual Studio 2003. It’s just that in Visual Studio 2005, Microsoft has opened it up a good bit more and made it a lot more accessible and usable.

At the time of writing (February 2006), the VSIP SDK isn’t finalised – it’s being rolled out on a two month ‘refresh’ cycle, so you may have to put up with some rough bits (mainly in the documentation and examples) and one or two bugs. The latest February SDK is pretty good though. Personally, I rather approve of the rolling release cycle. I’d far rather have something that’s pretty usable but not finished than have to wait about a year for the final product.

Packages

The key feature with the VSIP SDK is that you can define a  Visual Studio ‘integration package’ – something that can be loaded when you create a new project. For example, C# or Visual Basic would be considered packages.


Once you’ve registered with Microsoft and downloaded the SDK, you can create your own integration package, just like Visual Basic or C#.

But before you leap in and start producing your very own Visual Basic++, there are a couple of things to be aware of. First, before you can distribute any package you’ve built, you need to obtain a ‘product license key’ or PLK. Once you’ve installed the SDK, you’ll see a message on the splash screen ‘VSIP License Required’. In effect, when you download the SDK, you get a ‘development’ PLK (also known as a  DLK) which allows you to load your new package on a machine with the SDK installed. To get a production PLK you have to again apply to Microsoft – and it may (or may not) grant you one. I have to say that I don’t really understand the reasoning behind this – a PLK seems a pretty innocuous thing to me. Possibly a touch of paranoia?

Second, read the licence conditions. The licence isn’t the usual ‘we can do anything we want even though you’ve paid us good money’ sort of thing. You have to agree to produce code of a decent quality, incorporate your splash logo and not disable PLKs. All reasonable stuff, really, and I suppose most of it’s there to protect Microsoft’s Visual Studio reputation. In particular, it seems that you can produce ‘open source’ implementations provided you don’t try and GPL (the GNU licence) Microsoft’s source code.

Third, you should have at least a working knowledge of COM. Visual Studio is predicated on COM interfaces: Visual Studio lives, breathes and is COM. While you can get some way without knowing what COM stands for, at some point you’ll need to at least know what an ‘interface’ is and how to use one.

This last point has made adding things to Visual Studio difficult in the past. Unless you are a COM/C# expert, the best way of using a non-trivial COM interface is via C++. However, if you are using C++ and COM that probably means that you already are an expert. Somewhat circular, really – and it can be a little difficult to break into the circle.

Of course you can indeed use COM interfaces in C#, but I’ve found that debugging these can be tricky – you really need to see both sides of the COM interface if you have a problem. Also, you’ll find that not all COM types are supported by the CLR. One way round this is to write a C++ ‘shim’ that allows you to intercept and possibly modify the COM call before it goes into C#. Still, the Visual Studio COM interfaces are not simple – and there is a good number of them to master. So, in the past, unless you were pretty knowledgeable about COM, building a VSIP was far from simple.

With the Visual Studio 2005 SDK, Microsoft has engineered a decent solution to the skill level problem needed in using the Visual Studio COM interfaces from managed code. There is a new ‘managed package’ interface that allows you to use the Visual Studio COM services from C#. This is implemented via some C++ plus a good few C# classes. It really does simplify the way you can build a VSIP. After some initial scepticism, I was won over: the managed package framework is excellent.

Starting off

So now you’ve got the Visual Studio SDK installed, what next? There isn’t anything like an ‘idiots start here’ page and, while the documentation is reasonably comprehensive (and growing), it can be downright confusing. The main problem is that the managed package stuff is thrown in with the COM interface part, so at one moment you can be reading how to do something in C# and at the next moment you’ll find yourself directed to an obscure and ill-documented COM interface.


There are a number of sample applications to start from. Just select the most appropriate and use that as a base.

The good news is that there are plenty of example applications to chose from and, depending on what you want to do, it’s best to choose one of these. The first one I’ll look at here is the ‘Reference Package’ project. You’ll find this in the \VisualStudioIntegration\Samples\IDE\CSharp subdirectory of the SDK installation. Load up Package.sln in Visual Studio 2005. This illustrates a number of important VSIP points. The first thing you’ll see in the BasicPackage.cs file are the following lines:

[MsVsShell.DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\8.0Exp")]
[MsVsShell.PackageRegistration(UseManagedResourcesOnly = true)]
[Guid("01069CDD-95CE-4620-AC21-DDFF6C57F012")]
public class BasicPackage : MsVsShell.Package {

All packages have to start off  deriving from the Package class. This implements about a half-dozen or more Visual Studio COM interfaces so you don’t have the hassle of doing that. So here we’ve got BasicPackage as our fundamental class - you’d typically rename this to MyWonderfulProjectPackage or whatever.

Now look at the three lines above the class declaration. The first one declares which registry ‘hive’ we’re going to use:

[MsVsShell.DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\8.0Exp")]

It puzzled me when I first came across VSIP as to how you can develop an extension for Visual Studio without screwing up Visual Studio itself. The answer is that first of all Visual Studio stores all the information it requires about what products it’s got installed, what languages it knows about, etc in the registry. In particular, it stores the whole shebang under a key Software\Microsoft\VisualStudio\8.0 for VS 2005. But – and this is really neat - you can specify which key Visual Studio should look under by starting Visual Studio from the command line like this:

devenv /rootsuffix exp

This tells Visual Studio to look under the 8.0Exp key for its information and so you can keep code that you are developing completely separate from the code that is doing the developing, so to speak. You’ll almost certainly screw up the experimental registry in your first few attempts at working in VSIP, and you’ll be relieved to know that the experimental registry can be completely reset via an SDK menu command. This is nearly foolproof. Except, ahem, for the fool writing this. A word of caution: don’t try and test your package deployment into the non-experimental (production) VS hive on the same machine that you are developing on. I did – and I ended up having to remove and re-install the whole of Visual Studio after about a week of bizarre ‘impossible’ events.


Visual Studio stores the data it needs to develop Visual Studio Integration Packages under a separate ‘experimental’ Registry hive. If you screw up, it can be reset without affecting your main development environment.

Back to the example: the next line sets another attribute – it tells Visual Studio whether any user interface commands, etc., are in a satellite DLL:

[MsVsShell.PackageRegistration(UseManagedResourcesOnly = true)]

This is the way things used to be done; but, fortunately, all resources can be merged into a single assembly now. Setting this to true means that there is no satellite DLL and everything is neat and tidy.

The last attribute line declares a GUID (Global Unique IDentifier) for the class:

[Guid("01069CDD-95CE-4620-AC21-DDFF6C57F012")]

Don’t forget Visual Studio is COM based and COM means GUIDs. Lots and lots of GUIDs. Visual Studio expects the Registry to contain information about your package under a registry key Packages and so you must provide a GUID for it. Also, when you come to request a PLK for you finished product, you’ll need to provide this particular GUID to get a key, so don’t use the one in the reference package example. You can create your own easily enough in Visual Studio via the Tools/Create GUID menu item.

When you build your package, the MSBuild system will register these attributes in the experimental Registry hive automatically (I’ll look at the remarkable MSBuild – another well-hidden Visual Studio technology - in a later article). In passing, it’s interesting to note the use of attributes as a ‘declarative’ style of programming. Here, you don’t explicitly program a piece of code, instead, you declare what you want and something else comes along later and does it for you. The more the better: it removes a whole raft of rather boring coding from the program.


With Visual Studio 2005, Microsoft has completely redone the old makefile system for building projects, replacing it with the new MSBuild. It’s pretty damn good too.

You can build and run this example application from the SDK, but it doesn’t do a great deal. In fact, it doesn’t do anything at all. In order to, say, get the project to display in the list of available projects under Project/New menu, we have to do a bit more work. As I’ve commented above, the SDK is still a work in progress but not having a functioning basic reference project under the heading ‘Reference.Package’ is a little odd. However, if you do a bit more ferreting around, you’ll find an example that does the job. It’s carefully hidden away under VisualStudioIntegration\Archive\CS_Samples\Project. I’ll look at using that next month to get a simple text editor with some text colouring.

 

March 2006

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission