Reach into Visual Studio and pull all its strings with the Visual Studio automation object model.
The Visual Studio automation object model provides an interface for you to develop macros, add-ins, and other tools that access and manipulate the Visual Studio environment. Using this object model, you can access and change just about every part of Visual Studio.
In this hack, you will learn about the object model and some of the more useful tasks that can be automated using it. In this hack, I will not be focusing on macros [Hack 51], add-ins [Hack #89], wizards [Hack #88] , or any of the other ways that the object model can be accessed. Rather, I will focus on the object model itself and include small code snippets that accomplish a specific task. I will use macros as examples throughout this hack simply because they are easier for you to try out and test, but it is important to remember that these operations could be performed by anything operating against the object model.
|
MSDN includes a great reference to this object model. You can access
the MSDN
documentation through Help
The automation object model chart is particularly useful since it shows a visual hyperlinked representation of the entire object model, and you can drill down into the documentation for each class.
At the top of the object model is the DTE object. This object contains all of the classes and collections that you will be working with to automate Visual Studio. This is the object that your macro or add-in will reference and use.
Possibly the most frequently used object in the DTE is the Document object. Using the Document object, you can work with and manipulate any of the documents currently loaded in Visual Studio. You can work with two main properties on the DTE object to interface with the documents. The first is the Documents object, which is a collection of all the documents currently open in the IDE. The other property is called ActiveDocument and is a reference to the document that is currently shown in the document window.
Using just these two objects, you could write a macro to loop through the collection of documents and close all but the active document:
Public Sub CloseAllButActive( ) 'Declare and get an instance of the active document Dim active As Document = ActiveDocument Dim d As Document 'Loop through each document and if it [is? NE] not 'the active document close it For Each d In DTE.Documents If Not d Is active Then d.Close( ) End If Next End Sub
Another way to work with a document is to manipulate its actual text. Many of the macros in this book do this. To work with the text of the document, you will use the TextSelection object. The TextSelection object is a reference to the currently selected text, but it can really be used to change any of the text in the document.
The TextSelection object contains methods like StartOfDocument, EndOfDocument, StartOfLine, and EndOfLine. Something I commonly have to do is move existing text into a try . . . catch blockthis is something you could easily automate using the TextSelection object. Here is an example of a macro that surrounds the selected text with a TRy . . . Catch block:
Public Sub InsertTryCatch( ) Dim selection As TextSelection = ActiveDocument.Selection Dim text As String text = "try" & vbCrLf & " { " & vbCrLf & _ selection.Text & vbCrLf & "}" & vbCrLf & _ "catch" & vbCrLf & "{" & vbCrLf & "}" selection.Text = text End Sub
You would need to write a different macro to create a VB.NET TRy . . . Catch block.
The Documents object is extremely valuable. When writing macros and add-ins, this will probably be one of the more frequent objects you use.
The DTE object includes a Commands collection that contains all of the commands currently in Visual Studio. Commands are normally used by wiring them to a keystroke [Hack #24] or through the command window [Hack #46] , but you can also call them directly through the DTE.
To call a command directly, you simply need to call the ExecuteCommand method on the DTE object. Here is an example of calling this method:
DTE.ExecuteCommand("Edit.FormatSelection")
This code will execute the Edit.FormatSelection command, effectively the same as calling this command from the Command Window or through a shortcut key. You can get a reference to the actual command object through the DTE.Commands.Item method. Here is an example of getting a reference to this same command:
Dim com As Command = DTE.Commands.Item("Edit.FormatSelection")
Once you have the command object, you can add it to a command bar (more commonly known as a toolbar) [Hack #89] or even delete it if needed. The Commands object also includes an AddNewCommand method, which can be used to add custom commands for an add-in.
Visual Studio includes a large number of different windows. So many in fact that there is a hack in this book dedicated to just knowing how to best manage all these windows [Hack #16] . The Windows collection of the DTE object allows you to access these windows and work with them. To get a reference to a window, you will need to use one of the many vsWindowKind constants. There is a constant for each of the windows that can be shown in Visual Studio. Table 12-1 shows a list of some of the more common windows and their corresponding vsWindowKind constant.
Window |
Constant |
---|---|
Toolbox |
vsWindowKindToolbox |
Solution Explorer |
vsWindowKindSolutionExplorer |
Output window |
vsWindowKindOutput |
Properties window |
vsWindowKindProperties |
Command window |
vsWindowKindCommandWindow |
Here is an example of creating a reference to a window:
Window win = env.Windows.Item(Constants.vsWindowKindToolbox);
Using the Window object, you can set normal window properties, such as whether the window is visible or autohides, but more importantly, you can sometimes access more functionality. The toolbox is a great example of this. A Toolbox object can be accessed by referencing the Object property of the Window class. The following code shows how to get this object:
ToolBox toolBox = (ToolBox) win.Object;
Once you have the ToolBox object, you could then work with the toolbox [Hack #28] .
In addition to the objects covered in this hack, there are also objects that can access projects, solutions, the debugger, source control, command bars, macros, and much more. For more information, refer to the excellent MSDN documentation and some of the examples throughout this book.