Motivation

As a .NET architect and developer I cannot imagine my everyday work without Visual Studio. I was always in a strange excitement when waiting for a new CTP, Beta or RTM of Visual Studio because I always expected some great new features with every release. During the years I have bought a few third-party add-ins and utilities for Visual Studio to make my development tasks easier and even created small add-ins to produce some useful piece of code. I knew that Visual Studio was extensible; I downloaded the SDKs and tried to get familiar with those hundreds of extensibility interfaces. However, due to lack of good documentation I often got frustrated.

After the TechEd Developer 2007 conference in Barcelona I decided to get familiar with the most important aspects of Visual Studio Extensibility (VSX) and publish my gained knowledge in a “digested” way to give to the other VSX novices like me a few starting points. In the beginning of 2008 I started to share my experiences in the LearnVSXNow! project.

Visual Studio: Extensible Platform

Hearing the word “extensibility” a developer always starts to think “some API allowing extra functionality to be added to a product”. More or less, I can agree with this definition in the case of Visual Studio. In this part I tell you how I understand Visual Studio extensibility, and what are the ways we can add functionality. Because I started learning this story with the release of Visual Studio 2008, I put the focus on that version.

Thousand ways of extension

Well I know, it is an exaggeration to tell about “a thousand ways” when treating Visual Studio extensibility, but I’d like to point out that you have many choices. In this part I show you how many options you have when dealing with adding some extra stuff to Visual Studio. Reference materials, books, and articles generally enumerate about a dozen options. Instead of simply telling you what they are I would like to methodize them. The key to understand extensibility options is the architecture of the Visual Studio IDE:

Figure 1: Draft architecture of Visual Studio IDE

When running the Visual Studio IDE we start the devenv.exe file. However, the IDE we see and work with is not just a simple monolithic .exe file or an executable divided into a few .dll files. It is a shell that provides a graphical environment to host functional units, called packages. What we perceive is a cooperation of the shell and hosted packages. The core functions of the IDE are also implemented in packages including the C# or Visual Basic project types, testing features, and many more. The majority of third-party extensions loaded into Visual Studio are also implemented in packages. Just to give you a feeling about how many of them are used: in my notebook I counted 129 packages including those installed with Visual Studio 2008 and third-parties.

Packages contain visual and non-visual objects. The functionality they provide is encapsulated into logical services. I would like to emphasize the word “logical”, because the physical implementation of those services can be very different. In the figure above I used the SRV notation for services involved in packages.

If you look at the picture you can recognize why I mentioned “thousand ways” at the beginning. When we extend Visual Studio we can:

  • Organize existing service features and orchestrate new functions
  • Use the extension points and change or influence the behavior of services
  • Combine orchestration and extension points

To be precise, when we say we extend Visual Studio in many cases we actually extend services. It is true not only for the core VSPackages but also for the third-party extensions.

In my opinion when articles and reference books mention “options of extensibility” they confuse the physical method of implementation with the type of service to extend. I do not want to make the same mistake again, so let me clear the situation. First, I treat the physical methods we can use, then I show you the extensibility architecture, and last I enumerate a number of great options to extend Visual Studio.

Extension by configuration

The simplest method of extending Visual Studio or third-party packages is customizing it with the configuration features built in. In this case you do not have to write “traditional” code and build it. You actually extend Visual Studio behavior with changing the existing configuration or adding a new set of files.

Figure 2: You can extend Visual Studio by configuration or customization

To help your customization tasks, Visual Studio provides user interfaces, file format contracts, or often a combination of them. For example, you can add so-called code snippets to Visual Studio. The IDE provides UI for that: you can use the Code Snippet Manager utility to organize your snippets. Snippets are defined in XML files (the contract is defined by a schema) that can be saved with “.snippet” extension.

Some developers would not call it extensibility because “no code” has been added to Visual Studio but in my approach it is a simple and great form of “pumping value” into Visual Studio. Not only Visual Studio but also third-party packages prefer this model. For example almost all external refactoring tools provide UI or file templates to change the behavior or extend the refactoring patterns.

Extension by contract implementation

For developers the most common extension point is an interface representing a contract. To comply with that a service object implementing the contract must be created. It is the case also for Visual Studio. The IDE and the underlying packages define dozens (or about a hundred) of extension points in form of contract interfaces.

Figure 3: Services can be extended with other services implementing an appropriate contract

The following figure blueprints how it works for Visual Studio:

Orange components on the figure define services with extension points. Other service components can implement the contract coupled with that extension point. From the Visual Studio point of view the extender service component can be defined in the same package as the extended one, in a separate package, or even within an external component. A service object can work only if Visual Studio recognizes that it is an extension and is able to somehow connect it with the extended service. Visual Studio supports a few physical mechanisms to establish that connection:

  • Registration. The extender service registers itself in a way that Visual Studio recognizes it and binds the parties accordingly. For example, we can write our own designer and put it into a package. When the package is installed the necessary binding information goes into the system registry as a part of the setup process. Visual Studio accesses this information and handles the invocation of our designer: it loads and starts it when we edit a related project item.
  • Event driven binding. The binding is created dynamically as a result of an event or a user action. For example, we can write a logging add-in: when we turn the logging function on, it hooks into the solution events (this is when the binding is done). When we turn off logging, our add-in unsubscribes from those events.
  • Discovery. We put the component that contains an extension in a well-defined location (folder in the file system). Visual Studio recognizes it and uses some metadata information within the component to establish the binding. For example, we can create debugger extensions called visualizers. We put them into a user folder (or into a Visual Studio system folder). The visualizer is a .NET assembly that uses special attributes that Visual Studio understands so that it can show the visualizer when requested.

This kind of extension requires code that can be loaded into the memory space of the Visual Studio process in order to be invoked. The majority of developers take only this option into account as a “real extension”.

According to how this code is loaded into memory, the Visual Studio IDE supports two main options:

  • Packages. These components are implemented as dynamic link libraries. They must be registered with Visual Studio (as entries in the system registry under the corresponding Visual Studio key). Visual Studio loads packages when any of their objects or services is requested and they stay in the memory until Visual Studio is shut down.
  • Add-ins. These are COM components implementing a COM interface that allows an add-in to integrate with Visual Studio. When an add-in is loaded, it can access the majority of IDE tools and APIs in order to interact with them.

Packages and add-ins can implement their own mechanism to load further extension code. This is how the Visual Studio Debugger-it is a separate package-uses a discovery mechanism to load visualizers.

Automation

Most of us use macros because we have Microsoft Office: they make our life easier by automating repetitive tasks. Macros are available also in Visual Studio. They have their own UI within Visual Studio called Macros IDE. The key to writing and running macros is the automation mechanism:

Figure 4: Automation mechanism in Visual Studio

Visual Studio provides an automation interface where a great number of core services features are accessible through properties and methods of COM objects (indicated with OBJ on the figure). These automation objects form a hierarchy where we can navigate from one object to another, for example from the object representing a project to its project items.

Orange arrows point to automation objects representing services. The structure of objects is an expressive abstraction that reflects the natural relationship among objects better than the nearly flat structure of service interfaces behind them. Because of this abstraction the relationship between services and automation objects rarely is a one-to-one connection.

Not only core services can provide automation objects but also third-party packages and add-ins-including our own. The primary consumers of this automation interface are macros. You can create automation objects for your own extensions so that even they support macro recording! However, not only macros can access and consume automation objects. Packages and add-ins providing new features by “simply” orchestrating existing ones can leverage them.

Visual Studio Shell

As developers we use Visual Studio primarily for creating applications. I do not use the “writing code” or “programming applications” expressions intentionally. I think the way we use Visual Studio is going more and more away from typing code and closer to composing applications with the help of great GUI tools. From this aspect Visual Studio IDE can be categorized into two main parts:

  • Core functions of the IDE. These provide the services we use to create applications. The C#, Visual Basic, C++ project types and related designers, data designers, debugger, refactoring tools, etc. belong to this part.
  • Visual Studio Shell. The Shell provides an environment to host the core functions. Windowing services, text editors, menus, toolbars, output windows, tool windows (and many more) are general services provided by the shell.

Even the smallest extension can achieve extra value from the services provided by the Visual Studio Shell.

Imagine that you create a very simple database query application: users (non-developers) can select single tables from a business database and select fields. By pressing a button they can see the content of the table only displaying the selected fields. I know this example is strained but good for paraphrasing the value of Visual Studio Shell. When creating this simple extension, you can use a few shell features to create a professional looking and user friendly application.

Here are a few tips:

  • You can display tables and columns in a hierarchy similar to Solution Explorer or Server Explorer.
  • You can create a visual designer to select columns of tables and immediately see the results in a data grid.
  • One or more designers can be opened simultaneously and the user can organize them on the screen in a practical way, as tabbed views, docked windows, or floating windows.

From the release of Visual Studio 2008 you can use the Visual Studio Shell to enclose your extensions into a separate application. You can create your own Visual Studio extension, encapsulate it into the Visual Studio Shell and distribute it-internally, to communities, or to customers-freely but for a few licensing restrictions. Your target audience does not have to have Visual Studio installed or even have a Visual Studio license to run your application that uses only Shell features. Of course, when the extension you created uses Visual Studio core services beyond the Shell, for example the C# project system, your user must have a corresponding Visual Studio license.

Extensibility architecture

We have already seen that by using Visual Studio Extensibility we can add functions and features (and so developer value) to the Visual Studio IDE. We have also treated the different mechanisms (customization, contract implementation, automation) to show how this extension can be carried out. In this part we look behind these elements and discover the extensibility architecture.

Figure 5: Visual Studio Extensibility Architecture Components

When creating a component extending Visual Studio, we actually write applications. These applications at the end of the day use the core services in Visual Studio IDE. Visual Studio and Visual Studio SDK provides components to access core functionality. In the figure above I indicated them in the Service access layer.

Visual Studio is now ten years old. When it was originally designed and implemented COM was the ruling technology it had been built on. It cannot be gainsaid that the core stayed at its COM roots. When writing extensions today the majority of programmers use .NET to leverage the efficiency gains of managed code-based development.

The core IDE functions can be accessed basically through two APIs.

The Automation API provides COM objects to use the IDE functionality. COM Objects provided here form a well designed hierarchy starting with a common root object called DTE (Development Tools Extensibility).

The Package API publishes core services in the form of hundreds of COM interfaces.

The functionality offered by the Package API is much richer than the one accessible through the Automation API; however using it is much more complex than the automation. The main consumers of the Automation API are macros and Visual Studio add-ins. Generally, macros and add-ins tend to provide new features by composing existing ones, although add-ins are not restricted to this role only.

The Package API-as its name suggests-is used by developers creating VSPackages. Microsoft provides VSL (Visual Studio Library) for developing native packages (with unmanaged code). VSL is for C++ Visual Studio extension developers like MFC or ATL is for C++ application programmers.

Automation API and Package API offer COM objects. To consume them in the .NET world we need .NET Interop Assemblies. Those that are used with Add-ins to access the automation model (DTE) are installed with Visual Studio. Interop assemblies for the Package API ship with Visual Studio SDK.

Interop assemblies simply allow .NET objects to access the Package API services but do not change the nature and the model offered by the COM interfaces. The Managed Package Framework ships as the part of the Visual Studio SDK and provides object types that free developers from always creating the ground for their extensions.

Extension artifacts

When extending Visual Studio by creating code we have the following options:

  • Macros
  • Simple managed assemblies or native .dll files
  • Add-ins (native and managed)
  • Packages (native and managed)

We use simple .dll files (assemblies or native dynamic link libraries) for a few extension options. For example, we can add visualizers or custom MSBuild tasks. In this part I am going to examine primarily the three other options. First I tell you about the three main options then I make a short comparison and give you hints about using them.

Macros

Macros provide the easiest way to extend Visual Studio-we even do not need the Visual Studio SDK. Visual Studio has features to record macros and so we can automate repetitive tasks in a few minutes. Macros access the Visual Studio 2008 automation object model and easily combine Visual Studio commands with useful automation property values to get the desired behavior. To become a professional macro developer you need to know the object model behind the macros and a few dozen of patterns about using those objects. Visual Studio 2008 comes with a few macro samples to get a flying start. The best way to learn macro programming is to record macros and view recording results. You can extend this knowledge by borrowing coding patterns from the samples.

Although macros are great for task automation, they are not the right tools to create totally new functionality. When using macros, you should be aware of the fact that anyone can see the source code of your macro. Macros use a Visual Basic-like script language; you cannot use C#-like syntax. The following sample shows a small recorded macro initiating a new project creation:

Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
    
Public Module RecordingModule
    
    Sub TemporaryMacro()
        DTE.ExecuteCommand ("File.NewProject")
    End Sub
End Module

For simple tasks macros are powerful enough but they do not let you extend the user interface or the services of Visual Studio. Generally this constraint is why developers look for other options like add-ins and packages.

Visual Studio Add-ins

Add-ins are much more powerful for developing Visual Studio extensions, because you can access the Visual Studio 2008 object model and add new user interface elements to the IDE, such as tool windows, option pages, menu and toolbar commands, etc. The functions you add with an add-in look like they are part of the IDE. Your add-ins can access services provided not only by the IDE itself but also by other add-ins or packages. Branding is also available, you can display add-in product information on the Visual Studio splash screen or in the About dialog box. If you write a macro actually anyone can see the code you have written. An add-in is a compiled (.NET) binary, so you can use the same intellectual property-guarding techniques as for any other .NET binaries.

To deploy an add-in you simply create a setup project that produces an .msi file. Running this .msi file will do all the setup and registration tasks required for your add-in and you can immediately start to use it with Visual Studio.

Add-ins are COM objects that implement a simple interface called IDTExtensibility2 in order to integrate with Visual Studio. There is a project wizard in Visual Studio within the Extensibility project types named Visual Studio Add-in. It guides you through the basic steps of creating a frame for a simple add-in:

The wizard generates a great amount of code and comments to which you can add your own functionality.

Figure 6: Visual Studio Add-in project type

With the Visual Studio Add-in wizard you can create add-ins with both managed and unmanaged code, but unless you must use unmanaged code I strongly recommend using managed code (Visual Basic or C# according to your preference).

Visual Studio Packages

There is no doubt developing VSPackages is the most powerful way to add functionality to Visual Studio. The clear evidence for this is the fact that the whole Visual Studio functionality is build from packages integrated into the shell. All the languages, editors, the debugger, the project system and many more components are packages.

From a developer point of view it actually means that adding a new package to Visual Studio is just like adding core functionality to the Visual Studio IDE as if it were developed by Microsoft. The IDE does not make any distinction between Microsoft-created and third-party components; you see all packages as part of the Visual Studio IDE. Packages are binaries developed with your preferred language (C#, Visual Basic.NET or C++), so from intellectual property-guarding aspect they can be as safe as other .NET binaries.

From the deployment point of view, installing packages is a more complex task than setting up add-ins. Registration of packages affects a broader part of the Visual Studio registry entries and is helped by a utility called RegPkg.exe. Visual Studio checks if it can trust a package by a signing mechanism that uses a so-called Package Load Key. This PLK can be obtained from Microsoft and is a kind of digital hash for your package. When your package is installed into a production environment, its PLK is verified.

Visual Studio SDK ships a few extensibility project templates that make the creation of package frames as easy as an add-in.

Figure 7: Visual Studio Integration Package project type

In the figure above we are about to create a Visual Studio Integration Package (the most frequently used form of a package). The Visual Studio SDK also offers creating two special package types: Visual Studio Language Package and a Domain Specific Language Designer package. Well, if these are not enough, you can create your own package project types.

When to use macros, add-ins and packages?

After reading a short overview of the extensibility artifacts, a natural question arises: which one should I use for a certain extension task?

Macros are quite limited from a functionality point of view, because just a small part of the Visual Studio features can be accessed by using them and you cannot hide the macro source code. However, when this is not an issue and you want to provide an extension just to automate simple repetitive tasks, macros are your best friends. If macros constrain you because you want to add more than they offer you, add-ins and packages will be your saviors.

Add-in development offers a richer set of tools than macros. Besides using the Visual Studio automation model you can extend the user interface easily and consume services provided by other add-ins and packages. Because your code is compiled into a .NET assembly you can use the same deployment and intellectual property-defending methods as for any .NET binary. However there are a few extensibility options that are not available through the automation object model or through standard Visual Studio IDE services. In this case you cannot use an add-in, you must create a VSPackage.

Packages allow you to access all services, interfaces, and objects in the Visual Studio IDE. Almost all can be used in managed code with Visual Basic, C#, or other managed languages. However a few features require unmanaged code written in the C++ language. To use VSPackages it is not enough to be familiar with the automation model, you must be a good friend of several fundamental COM interfaces (altogether there are a few hundred of them). Developing packages also supposes that you know a few common VSPackage-related patterns and techniques like creating command tables, decorating packages with registration attributes, and so on.

In my opinion, if you plan to extend Visual Studio with sophisticated functions, then add-ins and packages are for you. If the automation model covers your expectations, you bravely can start with an add-in. However, in long term, if you really want to “feel the power”, learn VSPackage development.

In the next part about extensibility options I make references to the artifact types that can be used with a specific option.

Major extensibility options

We have already seen how extensions can be integrated into the Visual Studio IDE. In this part I treat the major extensibility options. A few articles and papers take into account macros, add-ins, and packages also as extension points; however, as I showed you in the previous parts I look at them as artifacts that physically integrate with the Visual Studio IDE.

If you remember I also mentioned that not only Visual Studio but also its extensions can be further extended. So treat the following enumeration as a starting point: you will be able to find some more options that are not on my list.

Code snippets

Code construction is an area where we face many repetitive development tasks. Code snippets target this area by helping us with inserting and customizing frequently used code structures like loops, switch statements and cases, property setters and getters, etc. Code snippets were introduced in Visual Studio 2005 and enhanced in Visual Studio 2008. Snippets allow you to create code templates with placeholders (parameters) that you can change. By their nature, snippets are language-dependent: for example a while loop uses different syntax in Visual Basic and in C#. Visual Studio 2008 provides tools to manage these snippets.

You can extend Visual Studio with your own code snippets by creating XML files with the .snippet extension.

Project and item templates

You know that Visual Studio ships with a few dozen project types to give you a starting point that best matches with your development plan. For example, when you want to create some code running on a server you can start with a Windows Service project type. During your daily work you can add items to your project depending on their functions (for example a simple class or interface, maybe a Windows form).

You do not have to stop at the templates Visual Studio ships. You can create your own templates for projects and individual items. You even do not need to write any code! The File|Export Template function provides a way to create a template from your existing code. As an advanced solution, you can create an assembly with a type that implements the IWizard interface to provide a wizard for your users. You can also create VSPackages that register their own project and item templates.

Extending the debugger: Type Proxies and Visualizers

The Visual Studio Debugger can be extended in many ways. One typical area is “to teach” the debugger handling “non-usual” source code types like a SQL Server stored procedure, an XSLT transformation or a JavaScript snippet. Although extending the debugger this way represents a typical option, it requires special knowledge and only a few developers will use it.

There are simpler ways to extend debugging features. Visual Studio allows you creating so-called type proxies: with them you can convert your types into other types that provide a better way to debug your variables. For example, if your original type uses LastName and FirstName properties, you can create a type proxy to display a FullName in the Watch window.

Visualizers are also a great option to help your debugging activities: they can create a view of your types that tells you better what is within your variables than the basic view. For example, if your type represents a binary tree, with a visualizer you can display it graphically instead of drilling down in the property tree displayed by the Watch window.

To extend Visual Studio with type proxies and/or visualizers you can create types decorated with special attributes and copy them into a folder watched by Visual Studio.

Menus, toolbars and commands

When adding new functionality to Visual Studio, generally we must provide a way to interact with the user. Menus and toolbars represent the first-line interface elements to access these functions. Actions behind a menu or a toolbar item often can be accessed from multiple locations or even can be called pragmatically. Visual Studio separates the concept of command-the action to be executed-from the user interface items used to activate that command.

When you create an add-in, you can extend the user interface through the automation objects. This is generally done in the setup phase of the add-in.

Packages also can extend the user interface with menus and toolbars, but they use a different method than add-ins. Packages use a so-called command table that describes the relation between commands and UI elements. This table is created during build time from an XML file having the .vsct extension. During the setup of a package this command table is put into the system registry. When Visual Studio starts, it knows what menus, toolbars, and commands a package has even without loading the package into the memory. When the time comes to load it, the package initialization code assigns commands with the code responsible for handling them.

Tool windows and document windows

Visual Studio has a full-fledged window support you can leverage. You can not only use existing windows (like the Error List, Task List, or Output window) but also create tool windows (like Solution Explorer or Class View) for your own UI elements, or even document windows to represent your project items.

The great thing is that your windows inherit the same behavior as the built-in windows: you can dock them, drag them to another location or make them float, and organize them into tabbed groups.

With the Managed Package Framework you can easily put the content of a user control into a window, so you can create UI extensions using standard Windows controls, Web controls or even the Windows Presentation Foundation (WPF).

Both add-ins and VSPackages allow you to create your own windows.

Editors and designers

We are far past that time when code editing or “Notepad-ing” was the only way to create applications. Visual Studio 2008 comes with a full-blown text editor and about a dozen visual designers such as the WinForms designer, ASP.NET page designer, XAML designer, resource designer, XSD designer, Class designer, and so on. Editors and designers are actually the same thing from the Visual Studio point of view: they help you to create your programming artifact. The documentation generally uses the word “editor” for both things. In my mind I associate “editor” with a UI that is based on text input like typing code. I call “designer” a graphical UI that either does not represent the programming artifact in text or hides from the user how textual representation is created.

You can create your own custom editor and integrate it with Visual Studio. Editors in the background make a clear separation of data-information being edited-and view-UI used to edit the information with related user interaction processes.

As the easiest form you can create a designer that uses a simple view, and associate it with a file extension. You can move toward more advanced editors that handle their own persistence model-they can even use databases at the back-and have multiple views.

Editors are generally defined in VSPackages. To create your own editor you must implement a half dozen of interfaces that define the contract required to be sited into Visual Studio. If you want to invest your editor with some additional integration features (for example support for macro recording, awareness of file changes, etc.) you must implement some more interfaces.

Custom project types and subprojects

Adding project and item templates can be a good option to start a customized project type based on an existing one. There can be situations where it is not enough because we would like to use a project system where we do not have an appropriate built-in project type to customize. Let me list a few situations:

  • We are not obliged to store our project system in files; we can use any abstraction of persistence. For example we can store information in a database (like the Database project type), in a remote FTP store, in a persistence engine, or even in a combination of these.
  • We might use project items that are represented in more than one file; however, we want to hide this fact from the user.
  • We want to use a special or prepared hierarchy of project items with their stereotyped behavior.
  • Our project has a completely different definition of how its artifacts should be built and deployed.

Of course this list is far from complete. In such cases you can create your own custom project types. One special use is to create subprojects-projects nested into other projects-or as Visual Studio SDK calls them, “flavors”. You are not constrained to create a project hierarchy used within the Solution Explorer window. Other hierarchies with similar project-like behavior also can be created. A good example is the Server Explorer.

Custom project types can be implemented only as VSPackages. Right now this is an area of VSX where it is quite laborious to implement and even to find usable helping information or samples.

Language Services

Not surprisingly, Visual Studio can be extended with programming languages. As we treated in the part describing Visual Studio IDE architecture, programming languages are implemented in packages-independently from the IDE-and “only” use the integration feature. In the same way as Visual Basic or C# has been created you can implement any other language including already specified ones and your own inventions.

Implementing a language and integrating it into any IDE gives you a long task list with such items like making a scanner (lexer) and a parser to process the language grammar, developing a good syntax-colored editor, producing a compiler or interpreter, adding debug support, etc.

The same tasks also should be done with the Visual Studio IDE. The Managed Package Framework provides a LanguageService namespace to help you with editor integration tasks like syntax colorization, brace matching, outline and command handling, etc. The Visual Studio SDK also ships a project type called Visual Studio Language Package that helps you create the lexer and the parser.

However, this project type creates a VSPackage in C++, C# and Visual Basic cannot be used with it.

Domain Specific Languages

We are used to programming our applications with general-purpose languages like C++, Java, C#, or Visual Basic. While these languages are good for describing generic programming constructs like methods and cycles, by nature they do not provide an efficient abstraction over narrow domain-specific concepts.

When our activities require performing much better on solving domain-specific tasks, general-purpose languages with their lower level abstraction cannot help. We need domain-specific languages to focus on the model and concept of the particular domain context.

Visual Studio SDK contains a great set of tools called Domain-Specific Language Tools to create your own DSL and integrate it with Visual Studio. DSL Tools use an approach that helps you produce a graphical representation of your language and provide text templating to generate code from your DSL model.

Visual Studio SDK registers an extensibility project type called Domain-Specific Language Designer. Using this package type, a custom DSL can be graphically designed.

This whitepaper does not intend to go beyond DSL. The book “Domain-Specific Development with Visual Studio DSL Tools” written by VSX Ecosystem Team members is definitely the best starting point.

Help extensibility

If we create some new functions to be used by others we can provide help for the targeted audience. Visual Studio Help can be extended: Help information for add-ins and packages can be merged into the Visual Studio Help at installation time.

More practically, not only Help files can be added but context-sensitive help can be provided. This context sensitivity goes beyond the simple model where “wired” code links a help topic ID to a UI control.

Visual Studio provides a model where pressing F1 allows access to the user context, and shows the corresponding Help topic and participates in Dynamic Help. We can create extensions that push information into the user context (for example in a custom editor) and dynamically determine the related Help topic accordingly.

Other extensibility options

Besides the aforementioned major extensibility options there are some less frequently used ones. Without listing them all-the list would never be complete-I introduce you a few of them.

Data Designer Extensibility

When creating .NET applications with Visual Studio we like to use data binding to put information coming from data sources together with properties of other objects. Data Designer Extensibility (DDEX) is the SDK to create and expose data source objects for Visual Studio.

DDEX provides a few dozens of managed types to be used in custom data source implementations. The structure of data object types managed by the custom source and the view representing their hierarchy can be defined in XML files based on schemas defined in DDEX.

Source Control Integration

It is natural for us that we can work in a team, and Visual Studio supports source code control operations like checking in, checking out, and locking source files. The whole concept of source control management in Visual Studio is implemented with the plug-in pattern: we can add source control providers to Visual Studio and select the one we want to work with.

This way we can extend Visual Studio to work with a custom source code provider.

Team Foundation Server Integration

Team Foundation Server is not part of the Visual Studio IDE but many development teams use its services and features through Visual Studio Team Explorer. You can extend TFS with work items, process templates, and custom builds, and you can even access the TFS API. The Team Foundation Server SDK provides you the main tool to customize it to your need. Besides providing access to the TFS core services it also provides extension points to work-item tracking, source control, data warehousing, and project creation.

TFS extensibility is a good example of an indirect Visual Studio extension. New features are added as extensions to the TFS related packages (like source control or Team Explorer) but from the user point of view they seem to be provided by the IDE.

System Model Definition SDK

The System Definition Model (SDM) is a tool for architects and system designers to create operable, manageable applications. SDM is a model to describe related software and hardware components, and resources running on a single computer or on a set of computers, including servers. System administrators, architects, and designers can create a live model of a system and with this model they can diagnose compatibility problems and deployment issues even before actually releasing the system.

The Distributed System Designers in the Architect Edition of Visual Studio 2008 Team System use SDM for application modeling. With the SDM SDK you can add model elements to the ones shipped with Visual Studio 2008.

In the introductory part of this paper I mentioned that a few years ago I gave up my intention to dive deeper into Visual Studio extensibility. It happened with me several times. The main reason was the lack of information about Visual Studio SDK and package development. Now my feelings are totally changed.

I hope that this whitepaper provokes you to have a closer look at VSX. To help you avoid the frustration I had and shorten your learning curve, in this paper I introduce the most important and valuable tools and resources, and I give hints about how to get a quick start with VSX.

Visual Studio SDK

To extend Visual Studio, installing the product itself is enough in many situations. You can write macros and add-ins using the automation model of Development Tools Extensibility (DTE). If you want to add more to Visual Studio, you cannot avoid learning features beyond DTE and package programming.

Visual Studio SDK is the essential set of tools for you. You can download it free from the VSX site; it is about 100 MB. When downloading and installing you get useful stuff:

You are allowed to create packages and start them under a so-called Visual Studio Experimental Hive. It is important because packages must have a valid Package Load Key (a kind of digital hash) in order for Visual Studio to load them. In the Experimental Hive (while you develop and debug) your packages are loaded even without PLKs.

Visual Studio SDK Browser lets you find information to help you in the learning curve. The browser groups information on four tabs. In my opinion the Samples tab is the one you will use most often.

Visual Studio SDK Reference documentation is also installed. You can use it to find reference information for VSX-related stuff just as for other Visual Studio and .NET things.

Visual Studio SDK comes with a bunch of tools and utilities to help your development process.

If you start VSX development from scratch, the documentation and samples in Visual Studio SDK will not help you to take a flying start. However, when you have a taste of what VSX programming means, samples included in the SDK will help you a lot. Instead of first reading through reference materials, browse through the samples that are close to your interest. You probably will find not only answers but also a context in which to try them and learn.

Visual Studio Ecosystem

In this paper I use the “VSX” acronym for Visual Studio Extensibility. It is much more than just a way to program.

VSX also represents a community around the extensibility aspects of Visual Studio. This community is actually a virtual ecosystem involving:

.NET developers not only using Visual Studio as a development environment but also extending it.

Visual Studio Industry Partner companies producing Visual Studio extensions, components, etc.

Development teams at Microsoft responsible for the Visual Studio SDK

A few years ago, extending Visual Studio was a privilege of VSIP partners. Even if it had a free-of-charge membership level, key information and important internals were available only with higher membership levels. In 2005, the Visual Studio SDK became free and all the technology is now accessible for any .NET developer. The VSIP program still has pay levels, but those are about marketing and support benefits and not about technology availability.

Now, Visual Studio Ecosystem is a growing community, where the key is the synergy among community members. I appreciate the power of the ecosystem: the end of my frustration related to Visual Studio extensibility development is due to the information coming from the community members and not just because Visual Studio SDK got better!

I guess the philosophy behind the ecosystem is simple and great. I like that the key driver for community growth is the passion for Visual Studio. Internal Microsoft team members-as they call themselves, the VSX Team-become the members of this community and also the community members become extensions of VSX Team.

The home of the ecosystem is the VSX site at http://msdn.com/vsx. Add it to your favorites!

Resources to start

I promised that I would give you hints about how to start with Visual Studio Extensibility. This whitepaper is just one from a set of other papers treating the different technical aspects of the Visual Studio platform. I suggest that you also read those papers.

Get into the picture

If you are new to VSX or just tasting it, Keyvan Nayyeri’s book about Professional Visual Studio Extensibility is definitely for you. Keyvan gives you a detailed overview about the important aspects and options of Visual Studio extensibility. This book is not about telling you all details, but rather to help you taste the pudding and how to go on in the direction that is significant for you.

I would like highlight a few chapters that will give you a good start depending on the topic you are interested in:

  • Chapter 22, Macros: This chapter of the book contains all essential information for those who address macro development.
  • Chapter 4, Automation Model; Chapter 6, The Anatomy of Add-In: These chapters give you a very good overview about what is included in the automation model and how to use it for add-in development. About five more chapters detail different functional parts of the automation model.
  • Chapter 18, VSPackages: You can find the fundamental information you need to know about why and how to develop packages.

I suggest reading or at least looking over these chapters because they can help you to decide which form of Visual Studio extension to use for your own tasks.

Due to constraints on its range, the book has only about 35 pages about VSPackage development. If you want to get started with package development and need something to help in the first steps toward, I suggest you the following links:

  • Visual Studio Extensibility User Education Team blog: The blog is the home of detailed tutorials and walkthroughs
  • LearnVSXNow!: My blog targeting VSPackage developers
  • Visual Studio Integration SDK Roadmap: A great topic within the Visual Studio SDK documentation to discover the main aspects of package development

Actually I faced many questions before getting and reading Keyvan’s book. The "How Do I?" Videos for Visual Studio helped me a lot because they not only told me what to do but also told why and how. When visiting this “How Do I” page, please scroll down fully: at the top you find Visual Studio videos (these are also useful); extensibility videos are on the bottom part of the page.

The main page of VSX contains links to VSX Team member blogs. Look at the blogs! Team members help you to understand what is happening at the heart of Visual Studio development. They indicate if they find great resources (tools, books, blog posts, etc.). By following those links you can reach valuable information.

Visual Studio Gallery

Visual Studio Ecosystem Team has a newborn child called Visual Studio Gallery. She (I have two daughters so a child is “she” for me...) is young but actually she has already left her childhood. Within the gallery you find extensions for Visual Studio coming from Microsoft, third-parties, and open-source communities.

For me this gallery is one of the primary sources because:

  • When I need a tool or I am thinking about some Visual Studio functionality for my projects, first I have a look at Visual Studio Gallery to find an existing one. It works for me and I often find tools for free!
  • There are many free trials so I can evaluate extensions before buying them.
  • Following the “Learn more” link in many cases-with open source tools-I can access even the source code. For me as an architect and developer a small part of source code tells more than books.
  • The gallery also helps me to guess whether there is a worked-out solution or tool for a particular area. Maybe I can make that tool...

I suggest that you browse this gallery. Even if you do not aim to develop Visual Studio extensions, you will find great tools there. Go back often and check for new content!

Summary

In this whitepaper I presented my understanding about Visual Studio as an Extensible platform and what the architecture of this platform is. I also introduced extensibility options. There are important messages for you to take away:

  • Visual Studio is extensible. If you do not find a feature or a function in Visual Studio it does not mean you have to do without it. There are many third-party extensions and open-source initiations; so you can probably find what you are looking for. If you don’t find exactly what you’re looking for, make your own Visual Studio extension. If you need some simple automation of development tasks, you can use macros. If you need some automation tasks requiring code, you can develop Visual Studio add-ins. If you need more sophisticated stuff, create VSPackages.
  • Almost everything is extensible is Visual Studio. Because Visual Studio has been architected with extensibility in mind, the question is not whether there are appropriate extension points for a feature of your imagination. The real question is what those points are and how you can add your features. Generally not only Visual Studio itself but third-party packages are also extensible, at least by configuration or customization.
  • You can extend it on your own. Forget about VSX as a privilege for just a limited group of developers! With Visual Studio 2008 SDK, C# and Visual Basic support you can take advantage of VSX just like you use other “traditional” forms of .NET programming such as WinForms or ASP.NET development. Of course, you need to learn new things, but this is the intellectual nutriment that refreshes our lives.
  • Start now! If you create some tool helping you in software development, Visual Studio should be in your mind not just as a development platform but also as a target for your tool. With the current tools of Visual Studio 2008 SDK, accompanying documents, and available resources, learning Visual Studio extensibility is easier than ever before.

Now there is a rapidly growing community, the Visual Studio Ecosystem behind Visual Studio. With any idea, imaginings, issues, or questions, you can turn to other community members and leverage the knowledge they have. Welcome to the world of VSX!

István Novák (DiveDeeper), Grepton Ltd.

April 2008