Key Skills & Concepts● Create an Add-In with VS ● Learn What Types of Add-Ins to Create ● Deploy an Add-In Previous chapters discussed many ways to use VS, and the preceding chapter show
Trang 1Extending Visual
Studio 2010
Trang 2Key Skills & Concepts
● Create an Add-In with VS
● Learn What Types of Add-Ins to Create
● Deploy an Add-In
Previous chapters discussed many ways to use VS, and the preceding chapter showed
you a few ways to create your own customizations In particular, macros offer the ability to perform repeatable actions and give you access to much of what VS has to offer Taking customization one step beyond macros, this chapter shows you how to extend VS functionality with a software component called an Add-In
Essentially, an Add-In is a software component that allows you to add new capabilities
to VS that haven’t existed before The Add-In plugs into VS, and you can run it as if it were part of VS This chapter shows you how the process of creating an Add-In works You’ll see how to add functionality to make an Add-In perform any task you want Besides creating an Add-In, this chapter points you in the right direction so that you can figure out how to access the different parts of VS The specific example in this chapter is an
Add-In that finds all of the shortcut keys in VS and prints them to the Output window With knowledge of how to create an Add-In, you’ll learn how to deploy the Add-In so that it can
be loaded into VS We’ll begin with a walk-through of how VS helps you create an Add-In
Creating a Visual Studio Add-In
As when creating other project types in VS, you can run a project wizard to create an
Add-In for VS The following discussion will show you how to start and run the Add-Add-In Project Wizard and examine the results
Running the Add-In Project Wizard
You would start the Add-In project the same way you would any other project The difference
is that an Add-In Project Wizard asks more questions than normal The following steps take you through the process of the Add-In Project Wizard and explain the various screens and questions you’ll need to answer
Trang 3Chapter 13: Extending Visual Studio 2010 373
1 Open VS and press CTRL-SHIFT-N to open the New Project window Select Other Project
Types | Extensibility and observe that there are two types of Add-In project types:
Visual Studio Add-In and Shared Add-In The Shared Add-In is what you would use
to create a Microsoft Office Add-In The Visual Studio Add-In is appropriately named
because it describes what we want to do Figure 13-1 shows what the screen should
look like
2. Select Visual Studio Add-In Name the project KeystrokeFinder, specify the location
where you want the project to be, and click OK Click Next to pass the Welcome screen and you’ll see the Select A Programming Language screen, shown in Figure 13-2
3 Pick the language you would like to use This book doesn’t discuss C++, but it would
be safe to pick either C# or VB, which you can learn more about in Chapters 2 through 4 Click Next to reveal the Select An Application Host window, shown in Figure 13-3
4 Your choices include Microsoft Visual Studio 2010 and Microsoft Visual Studio 2010
Macros Checking Microsoft Visual Studio 2010 will allow the Add-In to work in the
VS environment, which you’ve used for most of this book Checking Microsoft Visual
Figure 13-1 Selecting a Visual Studio Add-In in the New Project window
Trang 4Figure 13-2 The Select A Programming Language window
Figure 13-3 The Select An Application Host window
Studio 2010 Macros will allow this Add-In to work with the Macro Editor, explained
in the preceding chapter We’re only interested in VS for the current Add-In, so check only Microsoft Visual Studio 2010 (not the Macros option) Click Next to display the Enter A Name And Description window, shown in Figure 13-4
Trang 5Chapter 13: Extending Visual Studio 2010 375
5 The Enter A Name And Description window starts by appending “ – No Name provided.” and “ – No Description provided.” to the name of the project in the name and description
fields, respectively Just delete the defaults and add the name and description you want
the Add-In to have The Add-In will be named after what you put here, and users will
be able to read the description in the VS Add-In Manager, which I’ll discuss later in this
chapter Click Next to display the Choose Add-In Options window, shown in Figure 13-5
Figure 13-4 The Enter A Name And Description window
Figure 13-5 The Choose Add-In Options window
Trang 66 The first choice in Figure 13-5, “Would you like to create command bar UI for your Add-In?” will add a menu item to the Tools menu with the name of your Add-In Check the second box too, allowing the Add-In to load when VS loads; the alternative being that you can manually load the Add-In via the Add-In Manager, discussed later
in this chapter The third option comes into play when you want to allow the Add-In
to work when someone runs VS via the command line The preceding chapter shows
an example of running VS on the command line when installing the global project templates by running devenv /installvstemplates Popping up a modal window (one that requires you to click an OK button to make it go away) will stop a command-line operation from running because it is expecting acknowledgment of the modal window
If that command-line operation were running as a scheduled Windows background job, there would be no way to acknowledge the window and the job would not work So, check the third box only if it’s safe to run via the command line Check the first two boxes and leave the third box unchecked Click Next to move to the Choosing ‘Help About’ Information window, shown in Figure 13-6
7 You can optionally show an About window for your Add-In Check the box and modify the text that you would like to show in the About box Click Next and click Finish on the Summary window
After a minute VS will create a new solution and project that contains items that help you create an Add-In The next section discusses what those project items are
Figure 13-6 The Choosing ‘Help About’ window
Trang 7Chapter 13: Extending Visual Studio 2010 377
Examining an Add-In Wizard Solution
After running the New Project Add-In Project Wizard, you’ll have a solution with a project
that has skeleton code forming the basis of the application Not only will you need to know
what files are available, but you’ll also need to understand a couple of interfaces and how
to implement the interface methods properly If you’re a little rusty on interfaces, now
might be a good time to visit Chapter 4 for a review What you mostly need to know about
this project is that there are new references, a Connect class, and a couple of *.AddIn files
Refer to Figure 13-7 as we discuss each of these Add-In project items
Looking at assembly references (under the References folder), you might wonder
what all the assemblies are with EnvDTE names Pulling the name apart, Env is short
for environment and DTE means Development Tools Extensibility So, EnvDTE is an
assembly containing code that allows you to extend the VS development environment
Each assembly represents functionality for a particular version of VS: EnvDTE is for
VS.NET (the first version of VS that supported NET development) and VS 2003,
EnvDTE80 is for VS 2005, EnvDTE90 is for VS 2008, and EnvDTE100 is for VS 2010
(the subject of this book) The reason you need references to all of the EnvDTE versions
is that each new version builds upon the previous with new functionality, rather than
replacing the older version Therefore, you’ll sometimes encounter classes, interfaces, or
Figure 13-7 An Add-In project in Solution Explorer
Trang 8methods that are numbered, such as the IDTExtensibility and IDTExtensibility2, where
IDTExtensibility2 is a more recent version with additional members I’ll explain what the
IDTExtensibility2 interface does later, but what you should get out of this example is how
each version of the EnvDTE assemblies manages newer versions of code This scheme
promotes the addition of new functionality for each version of VS without sacrificing backward compatibility
The Connect class contains the code that interacts with VS to make an Add-In work
Remember, this is a VS project, just like all of the other projects you can create You’re
free to add classes containing your functionality and have code in Connect call your
classes, organize code into folders, or add a class library to the solution and call code in
the class library The next section discusses internals of Connect in detail.
The other items of note in this project are the files with the *.AddIn extensions These are the deployment files There was a time when you were required to go into the Windows registry to configure an Add-In, but not anymore The Add-In configuration is done in the *.AddIn files, which contains XML In a later section of this chapter, you’ll see the internals of the *.AddIn file and learn how to manipulate this file for deployment Additionally, one of the *.AddIn files has a shortcut arrow, which is a special shortcut
to a file used for debugging If you look at the properties for this shortcut file, you’ll notice that it points at your Documents\Visual Studio 2010\Addins\folder, which is a deployment location Whenever you debug this application, VS uses the debugging
*.AddIn file to load the Add-In in a new copy of VS You would manipulate the Add-In in the new copy of VS, and your current copy of VS, in debugging mode, can hit breakpoints and debug the Add-In
Now that you know the key elements of an Add-In project, the next section drills down
into the Connect class and describes the members that interact with VS to run an Add-In.
Drilling into the Connect Class
The Connect class implements two interfaces, IDTExtensibility2 and IDTCommandTarget,
and contains several members Before examining the code, you’ll learn about the interfaces, their members, and purpose
The purpose of the interfaces (IDTExtensibility2 and IDTCommandTarget) is to help
manage the lifetime of the Add-In VS understands these interfaces, but it doesn’t know anything about the code you write Therefore, you have to bridge the gap between your
code and what VS needs to make an Add-In work To do this, you use a class (Connect) that implements the interfaces (IDTExtensibility2 and IDTCommandTarget) Then you place your code into methods, members of Connect, that implement (match) the interfaces When
VS communicates with the interfaces, your code (implementing the interface) executes
Trang 9Chapter 13: Extending Visual Studio 2010 379
It’s like people from different countries trying to communicate, where they have a subject
to discuss but need a common language to be able to understand each other; the common
language would be the interface between the people
The first interface to discuss is IDTExtensibility2, whose purpose is to let VS manage
loading and unloading of the Add-In Loading and unloading are important because VS
loads Add-Ins when it starts and unloads Add-Ins when it shuts down There are certain
actions that you might want to take, depending on when the Add-In is loaded and what
type of information you might need access to For example, the very first time an Add-In
is ever loaded, you might want to perform a special operation like configuration or asking
the user if she would like to register your Add-In Table 13-1 shows the members of
IDTExtensibility2 and describes their purpose
The second interface that Connect implements is IDTCommandTarget When building an
Add-In, you need a way for the VS IDE to execute the Add-In For example, you will create
a named command that exposes the Add-In as a menu item in the Tools menu Whenever
a user selects the menu item, the named command will execute and run your Add-In code
IDTCommandTarget is the interface VS uses to execute your Add-In Table 13-2 shows the
members of IDTCommandTarget and describes their purpose.
Each of the methods of both the IDTExtensibility2 and IDCommandTarget interfaces are implemented by the provided Connect class Listing 13-1 shows each of these members with
full documentation comments and skeleton code The code in Listing 13-1 is in C#, but it is
very informative to take the overview of the interfaces from the previous table and then
Table 13-1 The IDTExtensibility2 Interface
Table 13-2 The IDTCommandTarget Interface
Member Purpose
invisible, or supported.
Trang 10take an even closer look at the comments in the code for a better understanding of what that code does The code comments are exactly the same in VB Some of the comments refer to the host application, where the host is either the VS IDE or the VS Macro Editor, as was selected while running the Add-In Project Wizard in the preceding section and shown
in Figure 13-3 I’ve removed the contents of each method because subsequent sections of this chapter will explain important method implementations and how to make the Add-In perform useful operations
Listing 13-1 Skeleton code for the Connect class
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;
using System.Resources;
using System.Reflection;
using System.Globalization;
namespace KeystrokeFinder
{
/// <summary>The object for implementing an Add-in.</summary> /// <seealso class='IDTExtensibility2' />
public class Connect : IDTExtensibility2, IDTCommandTarget
{
/// <summary>
/// Implements the constructor for the Add-in object
/// Place your initialization code within this method
/// </summary>
public Connect()
{
}
/// <summary>
/// Implements the OnConnection method of the
/// IDTExtensibility2 interface Receives notification
/// that the Add-in is being loaded
/// </summary>
/// <param term='application'>
/// Root object of the host application
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded
/// </param>
Trang 11Chapter 13: Extending Visual Studio 2010 381
/// <param term='addInInst'>
/// Object representing this Add-in
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(
object application, ext_ConnectMode connectMode,
object addInInst, ref Array custom)
{
}
/// <summary>
/// Implements the OnDisconnection method of the
/// IDTExtensibility2 interface Receives notification
/// that the Add-in is being unloaded
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(
ext_DisconnectMode disconnectMode, ref Array custom)
{
}
/// <summary>
/// Implements the OnAddInsUpdate method of the
/// IDTExtensibility2 interface Receives notification
/// when the collection of Add-ins has changed
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref Array custom)
{
}
/// <summary>
/// Implements the OnStartupComplete method of the
/// IDTExtensibility2 interface Receives notification
/// that the host application has completed loading
/// </summary>
/// <param term='custom'>