Virtual Developer Workshop: Containerized Development with Docker
The Visual Studio 2005 Integrated Development Environment (IDE) has an abundance of features. These include support for all of your favorite .Net languages, out—of—the box solutions (i.e., web sites, windows forms, mobile applications, etc.), built in refactoring and code snippet support, Intellisense, a sophisticated compiler, among other elements.
What really sets Visual Studio 2005 apart from its predecessors (and its competitors) is the advanced extensibility options. As a developer, you can build macros to bind to key stroke combinations or toolbar buttons, develop Add—ins to enable the addition of new features, or build VS Packages through the Visual Studio Industry Partner Program to enable the integration of entire products or advance customizations into the IDE.
Although the primary focus of this article will be the fundamentals of the VS Package, the other three extensibility levels will also be discussed. Additionally, I will walk you through the development of a managed Visual Studio 2005 Package, explore some of the Managed Package Framework (MPF), and take a look at the Visual Studio SDK Interop assemblies.
Levels of Extensibility
Visual Studio 2005 (VS 2005) provides you with three levels of extensibility, with each level increasing with power and functionality. First, the easiest way to extend Visual Studio is to record a macro. Recording a macro is extremely simple and provides you with the ability to record almost all commands and keystrokes. Additionally, macros give you access to nearly all of the Visual Studio automation object model, which contains more than 140 objects and provides you with full access to the .Net framework.
Macros are not new. Office developers have been using them for thousands of years and they have been an integral aspect of most Microsoft automation models.
Unfortunately, for all of their functionality, Macros do have some legitimate drawbacks. To start with, they can only be written in the Visual Basic language, limiting their usability to a somewhat narrow audience. Next, Macros cannot be used to implement new tool windows, commands, or Tools Options pages. Finally, macros are not compiled, which means you have less control when trying to protect your intellectual property.
The next level in the hierarchy is a VS 2005 add—in. Add—ins provide you with full control over the Visual Studio automation object model . This ability facilitates the interaction with most of the tools and functionality in the VS 2005 IDE. This includes but is not limited to the Text Editor, Output Window, Task List, and Code Model. Additionally, there are very few barriers to developing an add—in because there is an out of the box Add—in Solution and Wizard in VS 2005.
Unlike Macros, Add—ins can be written in any language that supports COM including Visual C#, VB.Net, and Visual C++. Add—ins are compiled as DLLs which also means you have greater flexibility in protecting your intellectual property. Furthermore, unlike Macros, Add—ins can implement new Commands, Tools Options pages and Tool windows. However, Add—ins cannot implement new document types, new project types, new debug engines, etc. which all require the next level of extensibility.
Packages, are the third a final level of extensibility in the Visual Studio 2005 hierarchy of extensibility. Packages in previous versions of Visual Studio.Net would have required some investment from the developer, but with the new VSIP program for VS 2005, Microsoft has added a free participation level. Packages are on the top of the pyramid; they will provide you with more flexibility than is available through an Add—in or a Macro.
When developing a package you can use C# or C++ to access the Visual Studio SDK. At this point, its worth stating that developing a VS Package is not for the faint of heart.
Although you can get by developing a Package without any knowledge of C++, you are going to have a lot less gray hair if you have a solid understanding of the fundamentals of C++, such as header files and interfaces.
After you register with the VSIP program and download the 100+ MB SDK, you can start building applications that truly extend the IDE. Some examples of tasks that can be performed in a package include: customizing editors, creating new projects types, integrating debug tools, and integrating new languages.
One caveat worth mentioning is that if you plan on commercially marketing any package you will need pay into the VSIP partner program. Plus, as most would assume, the developers license key distributed with the SDK cannot be used for distribution. To distribute a VS Package one needs to apply for a product license key (PLK) from Microsoft.
Managed VS Packages
While the functionality found in Add—ins and Macros is extremely useful, there is already a lot of documentation out there on these subjects. Not to say that the help files and the samples with the VS SDK are bad, because theyre not, but many of them are complicated for non C++ developers because they refer to C++ interfaces, use Hungarian notation, and use COM terms like IUnknown, Co—Creatable, etc. that many new developers will not be familiar with. Additionally, there are many significant changes to the VS SDK that need to be examined.
The VS 2005 SDK supports several new and enhanced features to make it easier for you to integrate your programs into VS 2005. The first new feature is the MPF. The MPF enables you to develop packages in managed code using C# or VB.Net. The MPF is a significant upgrade from the VSIP 2003 program because it provides default implementations for many of the more complicated COM interfaces.
You may be wondering why I keep mentioning COM. Well, if you havent figured it out yet, Visual Studio is developed using COM objects. What this means is you should be prepared for GUIDs and cryptic interface names. Fortunately, when using managed code you have two layers of abstraction from the underlying COM Interfaces as illustrated in Figure 1.
As Figure 1 shows, when developing a managed package there is a hierarchy of assemblies. Although I wish I could say that you will only be interacting with the MPF, the fact is you will probably need to access the Visual Studio Interop Assemblies directly to retrieve handles to various interfaces. Both scenarios will be explored further in the example later in this article.
So, you are probably wondering what you can actually do with the MPF? Lets look at some specifics.
The MPF can help you all of the following points of extensibility:
- Tool Windows / Document Windows
- Creation and manipulation
- Adding Commands
- Command Routing
- Tools Options, Automation model additions and VS Settings participation
- Made much easier and can use the same underlying code to handle all these areas
- Package Registration
- Accomplished through declarative code attributes
- Extensible by 3rd parties
- Task List / Error List integration
- Properties window integration
For the most part you can accomplish the majority of tasks through the MPF. Some examples of places where you will have to dive into the interop assemblies include: language services, editors, and debuggers. Additionally, there are cases where you will have to use a combination of the MPF and the Interop assemblies to accomplish your goals.
The final point worth mentioning before we move into an example is the fact that the MPF and the Visual Studio SDK assemblies are completely separate from the automation model (different namespaces, assemblies, etc.). Although there is overlap in functionality, the VS SDK hooks directly into the core of Visual Studio while the automation model, which is stored in the EnvDTE and EnvDTE80 assemblies, works through a higher level layer of abstraction. With that said, there is no reason why you cant use the automation model in your VS Package, in fact it is probably recommended in some cases. I just want to make sure that we are clear, and that nobody misunderstands and thinks that they worked with the SDK by using EnvDTE for an Add—in.