Although the automation model can be more fun than a barrel of monkeys, add-ins let you really extend the environment.
In this book, you have learned about a large number of different add-ins that you can install to enhance the functionality of Visual Studio. In this hack, you will learn how to write one of those add-ins. The topic of writing Visual Studio add-ins can be, and has been, the topic of entire books, so needless to say, this hack will simply be an introduction to the topic.
Add-ins are installable extensions to the Visual Studio IDE. Through add-ins, you can accomplish quite a bit with the IDE. An excellent example of this is TestDriven.NET [Hack #93], an add-in that really adds significant functionality to the IDE.
I am not going to attempt anything that grandiose for this hack. Instead, you will learn how to create a simple add-in that adds an item to the Tools menu and to the right-click menu that will allow you to select text and then click the menu item to surround that code with a try . . . catch block.
To get started, you will first need
to create a new add-in project by going to File
This launches the Extensibility Wizard shown in Figure 12-5.
Click Next to move to the first screen of the Extensibility Wizard, shown in Figure 12-6.
In the first screen of the wizard, you choose what language you want to use to create this add-in. In this example, I will use C#, but you can also use Visual Basic or Visual C++. After choosing the language, click Next and you will see the Select an Application Host screen (shown in Figure 12-7).
On the Select An Application Host screen, you choose what application hosts you want your add-in to be compatible with. The choices are the Microsoft VSMacros IDE and the regular IDE. It is a good idea to enable your add-in for the VSMacros IDE only if you think users will really get value out of using your add-in in that IDE. In this case, the add-in could indeed be useful from the macro IDE, so I will leave both of these checked.
When you click Next, you will see the name and description screen shown in Figure 12-8.
In the name and description screen, you get to name your add-in and provide a brief description of the tool. Clicking Next will show you the options screen shown in Figure 12-9.
The add-in options screen includes a number of options for how you want your add-in to work. Here are the options you must decide upon on this screen:
This option decides whether a menu item will be added to the Tools menu. Having this button on the Tools menu does not mean that you will need to create a complex UI by any means. In this example, I am going to check this box because I want users to be able to click a button in the Tools menu to insert a TRy...catch block.
This option decides whether your add-in can be used during command-line builds [Hack #78] . You need to check this box only if your add-in will never show a modal UI and if your add-in would benefit from being loaded during such a build. Since this add-in is strictly a coding add-in, I will leave this box unchecked.
This option decides if the add-in will be automatically loaded. This can always be configured and changed by the user, so I am going to uncheck it. There is no reason to force the user to load the add-in every time.
This option determines whether the add-in will be available to all users or just the user who installs the add-in. Unfortunately, the install program does not ask the user to make this choice during the install process so it is usually a good idea to leave this unchecked.
After you have configured the add-in options for your add-in, you can click Next to be shown the help about screen, which is shown in Figure 12-10.
The help about screen lets you configure whether an About box should be enabled for your add-in and, if so, what should be included in that box. When you click Next, you will see the Summary screen shown in Figure 12-11.
After completing the wizard, you will see two projects in the Solution Explorer, a class library and a setup project. You will also notice a file called Connect.cs, as shown in Figure 12-12.
Visual Studio also adds a great deal of the boilerplate code to the Connect.cs file for you. If you open it, you will see all of the required methods already created with default code. You could actually run this add-in already, and it would handle the commandit just wouldn't do anything.
Since you checked the Tools menu option in the project wizard, Visual Studio will have already added the command for your add-in to the Tools menu, but you usually want to also have a menu item somewhere else. In this example, I want to have a menu item also on the right-click menu. To do this, you will need to modify the default code that the wizard generated.
When your add-in is loaded, Visual Studio calls the OnConnection methodthis is where you will need to add commands. Here is the default code created by the wizard:
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) { applicationObject = (_DTE)application; addInInstance = (AddIn)addInInst; if(connectMode = = Extensibility.ext_ConnectMode.ext_cm_UISetup) { object [ ]contextGUIDS = new object[ ] { }; Commands commands = applicationObject.Commands; _CommandBars commandBars = applicationObject.CommandBars; try { Command command = commands.AddNamedCommand(addInInstance, "TryCatchMatic", "TryCatchMatic", "Executes the command for TryCatchMatic", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported +(int)vsCommandStatus.vsCommandStatusEnabled); CommandBar commandBar = (CommandBar)commandBars["Tools"]; CommandBarControl commandBarControl = command.AddControl(commandBar, 1); } catch(System.Exception /*e*/) { } } }
The boldfaced code is the section that actually creates the command and then adds it to the Tools command bar. Using the same Command object, I am also going to add it to the Code Window command bar, which represents the right-click menu when inside the code window. First, you need to create a CommandBar object and get a reference to the correct command bar, then add your command to that command bar using the AddControl method. You should insert these two lines after the last line within the TRy block:
CommandBar commandBar2 = (CommandBar)commandBars["Code Window"]; CommandBarControl commandBarControl2 = command.AddControl(commandBar2, 1);
This command will now show up on the Tools menu as well as the right-click menu in the code window after the add-in is installed. For information on how to find the various command bars in Visual Studio, please refer to [Hack #90].
You will most likely also want to add something to the catch block, since the code created by the wizard simply "swallows" the error. You can write the exception using Debug.WriteLine or implement some other method of handling the exception.
The next step is to write the code that will do the work of the add-in. In this example, I will be writing a simple piece of code that surrounds the selected text with a try . . . catch block. This code needs to be added to the Exec method that was added for you by the wizard. Here is a look at the default code:
public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) { handled = false; if(executeOption = = EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault) { if(commandName = = "TryCatchMatic.Connect.TryCatchMatic") { handled = true; return; } } }
This code first checks the executeOptions and then checks to see if the command being called is the command for this add-in. Inside the last if statement is where you will write the code for what your add-in will actually do. Here is the code I have added to get the currently selected text and then surround it with a try...catch block:
if(commandName = = "TryCatchMatic.Connect.TryCatchMatic") { string selectedText = textDoc.Selection.Text; string newText = "try\n { \n" + selectedText + "\n}\ncatch\n{\n}"; textDoc.Selection.Text = newText; handled = true; return; }
In this code, I get a reference to the ActiveDocument and then get the selected text. I can then replace the selected text with the new, surrounded text.
When you are ready to install and test your add-in, it is pretty simple to do so, since the wizard automatically added an installer to the project.
|
Next, you will need to build the installer, as it is not built by default. You can do this by right-clicking on the project and clicking Build. After the project has been built, you can right-click on the installer and click Install. This will install your add-in on your machine. Next, you will need to close and then reopen the IDE, and you should see your menu items. If you do not see your menu items, make sure that your add-in is enabled in the add-in manager and then try running devenv /setup [Hack #92] .
This hack has been a quick introduction to the development of add-ins, but there is a lot more to learn. Here are some great resources to help you learn more about add-in development:
http://msdn.microsoft.com/vstudio/extend
http://groups.yahoo.com/group/vsnetaddin
http://blogs.msdn.com/craigskibo