isual Studio .NET provides an incredible leap forward from its predecessor in terms of functionality, but eventually, every developer finds a sought-after feature that just seems overlooked.
VS .NET provides great features and capabilities, from intelligent wizards to very useful drag-and-drop functionality such as that provided by the Server Explorer tool window. If there’s a problem, it could be one of too much success. A simple stroll through the IDE reveals feature after productivity-inducing feature, providing the developer with a high set of expectations. Eventually, you may find that an expected feature is missing. Fortunately, Microsoft included a very powerful extensibility model, allowing integration of new, custom features directly into the IDE.
Microsoft has provided extensibility and automation object models for most of their products for as long as one can remember. For example, the automation model exposed by Microsoft Office provides the foundation of the entire VBA community. When you work within the world of the developer, the strength and power of the developer’s tools will dictate productivity. The ceiling on productivity achievable by a developer bears a high-correlation with the number and usefulness of the features provided by the IDE. If you make the IDE better, developers will rejoice. Herein lays a major problem. For all the R&D money and general efforts placed into the design and development of it’s products, Microsoft understands that it can never anticipate all the features the entire developer community might need or want. If they attempted to achieve that goal, the natural result would invariably be to occasionally actually ship an IDE?maybe once a decade or so.
This makes me think of the analogy of the fisherman. Give a man a fish, and he will eat for a day. Teach him to fish, and he will eat for a lifetime. In similar fashion, if you trade fish for features, the moral of the story stands. It’s better to give the developer the tools to create new, custom features, than to try and anticipate all the features that developers need. This is where the extensibility model of Visual Studio .NET, found in the EnvDTE and Extensibility namespaces, plays a role. Using these namespaces as a primary toolkit, the power developer will create extended capability and features, in the form of add-ins, that evolve the IDE into the customized power tool that can address all of the developer’s needs. In essence, if the developer plays the role of the fisherman, than the extensibility model is the net in .NET.
A Brief Comparison to Macros
|Figure 1: The Visual Studio macro server process, vsmsvr.exe, handles the execution of macros outside of the IDE process, devenv.exe|
Before jumping into the guts of what an add-in entails, or how the architecture of the IDE interacts with these special classes, let me explain the relationship that macros and add-ins have to one another. Macros play a special role by providing the developer with a quick and simple mechanism for defining custom behavior and functionality. Macros allow the development of custom functionality, but carry significant limits in terms of deployment, performance, and functionality constraints. Both fundamentally use the same extensibility API, EnvDTE, to perform all of their fancy footwork. Similarities tend to end there. For example, the language used to write macros within the IDE is limited to Visual Basic .NET. Since macros tend to exist to perform simpler, more straight-forward tasks of an automation nature within the IDE, using Visual Basic .NET as the macro language provides a more natural fit. This approach mirrors the “Great for simplicity” strategy, but consequently falls short of providing an ideal situation for the predominantly C# developer.
VS .NET saves macros in files with a .vsmacros extension, while add-ins are .NET classes compiled into DLL assemblies. Compiling add-ins into assemblies highlights a fundamental difference: macros run out-of-process with the IDE, while a DLL containing an add-in class achieves better performance by running within the IDE. Macros run within a vsmsvr.exeprocess, in comparison to the IDE, or devenv.exe. You can see this in Figure 1 where I recorded and then ran a macro while I had the Task Manager open. Compiling add-ins into assemblies also provides a layer of intellectual property protection (security) that is not afforded to macros, which are essentially distributed along with their source code.
|Basic Add-In Architecture
The team responsible for designing the extensibility API in Visual Studio .NET stipulated few requirements for a .NET class to have the ability to function as an add-in. The Visual Studio .NET Add-In Project type provides a wizard to generate a great deal of basic coding elements that have the tendency to hide the bare essence of what is actually required. Later I’ll show you the results of using this Project type as a starting point for your add-in, but for now, let’s stick just to the bare facts.
These assemblies will provide the core interfaces you will need to implement and the access to the primary interop assembly for the Office menu controls, allowing use by your add-in of the core set of UI controls used by Visual Studio .NET for the command bars, context menus, and menu items.
Most add-in projects will greatly benefit from the use of a core set of imports statements at the top of the code file.
Meeting the Three Primary Requirements