Paul Kimmel on VB/VB .NET : Creating Visual Studio .NET Add-Ins, Page 2
Implementing the IDTExtensibility2 Interface
The Add-In wizard provides an implementation for OnConnection automatically. OnConnection initializes the applicationObject and the AddInInstance references. These objects are used to create and insert a NamedCommand and add a menu item to the Tools menu on lines 34 to 67. The applicationObject references refers to the Development Tools Environment (DTE), which is the root object representing the host IDE. The addInInstance object is a reference to the specific instance of the Add-In, ensuring that an invocation refers to a specific object instance.
The other four IDTExtensibility2 interface methods are implemented as empty procedures. Add code to these procedures if you need additional code for initialization, startup, or de-initialization.
Implementing the IDTCommandTarget Interface
The IDTCommandTarget interfaces are implemented too. QueryStatus determines if the command is available, returning this state in the statusOption parameter, and Exec is represents the point of invocation.
Choose to implement those interface methods that you need to support your Add-In and leave the rest as empty procedures. Insert your response code between lines 76 and 77; for example, you might simply insert DoExecute method and implement your custom behavior beginning in the DoExecute method.
|Tip: Other things the Add-In wizard does for you include creating the setup project, creating strong name key file, configuring debug properties, indicating that the devenv.exe (VS.NET IDE) is a host application for your Add-In. (Remember class libraries must be executed by a host application.)|
Insert the statement MsgBox("MyAddIn") on line 77 and press F5 to run and test the Add-In. Pressing F5 will run a second copy of Visual Studio.Net with the Add-In available on the tools menu. Click the new Add-In menu item, and you will see the message box with the text MyAddIn displayed. (Keep in mind that the setup target created by the wizard will be compiled too, so be patient when you press F5. Building both the Add-In and setup project may take a couple of minutes.)
Debugging Add-Ins in Visual Studio.Net
Before you register your Add-In and put it into general purpose use you can debug it from VS .NET. The wizard sets debug properties indicating that VS .NET the host application. When you press F5 VS .NET will run another instance of the IDE and allow you test your Add-In. Set a break point in the source code of the Add-In in the first instance of the IDE. When you run your Add-In from the second instance it will halt when you breakpoint is hit. At that point you can debug your Add-In as you would any other application.
Add-Ins are assemblies. You can register Add-Ins as private assemblies for personal use or in the Global Assembly Cache (GAC) for shared used. Both types of registration are covered here.
Private Assembly Registration
Applications, like an Add-In DLL, have application settings that are stored in the Registry. You may have heard that .Net assemblies support xcopy deployment. This is true of .Net assemblies but not of .Net assemblies that are used by COM-based applications. Add-Ins use the system.Runtime.InteropServices which suggests that Add-Ins are used by COM-based applications, specifically the Add-In manager. For this reason you will need to register your Add-Ins. Additionally you will need to add registry settings allowing the Add-In Manager to display the Add-In in the Add-In Manager.
|Caution: Anytime you modify the registry ensure that you export and maintain a backup of your master registry file.|
There are several steps that you must perform to register your Add-In assembly. The first thing you need to do after you have tested your assembly is to run regasm.exe. The regasm.exe utility is found by default in the \winnt\Microsoft.Net\Framework. The command to register an assembly is
regasm <path\>myaddin.dll /codebase
where myaddin is the name of your Add-In, including the path information. The second step is to add information, instructing the Add-In manager how to make your Add-In accessible. You can create a registry script by copying the structure of the following listing in a text file with a .reg extension.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\AddIns\MyAddIn.Connect]"FriendlyName"="MyAddIn""Description"="My First AddIn""LoadBehavior"=dword:00000001"CommandLineSafe"=dword:00000001"CommandPreload"=dword:00000001
Figure 1: Registry entries describe the Add-In in the Add-in Manager.
|Note: You can construct the keys necessary from the registry while you are debugging the Add-In because the keys are added during debugging. Unfortunately those keys are removed intentionally or accidentally after debugging is complete. Store the keys in an external registry file by exporting the Add-In keys from the registry editor. (Additionally, there is a reminder that you may have to load the ReCreateCommands.reg keys into the registry if the Add-In stops showing up. Unfortunately, during early versions of beta 2 none of these remedies seem to be reliable.)|
The preceding registry script adds a key to the registry. Replace MyAddIn.Connect with the namespace and class of your Add-In. (Connect is the class name created by the Add-In wizard by default.) FriendlyName is the name of the Add-In that is displayed in the Available Add-Ins list of the Add-in Manager (see figure 1). Description indicates the text shown in the Description field, and the three remaining keys indicate the load behavior of the Add-In.
Shared Assembly RegistrationShared assemblies are stored in the Global Assembly Cache, called the GAC. The GAC can be viewed by navigating Windows Explorer to the \winnt\assembly folder. When you navigate to this folder the GAC snap-in is automatically loaded by Windows Explorer (see figure 2).
Figure 2: The Global Assembly Name cache folder: a plug-in used by Windows Explorer automatically when you navigate to the \winnt\assembly folder.
Global assemblies can be shared. Global assemblies are distinguished by the string name, public key rather than the file name. Hence you may have more than one file with an identical name in the GAC, but you will need to generate a strong name for shared assemblies. Strong names are generated by the Add-In wizard, or you can explicitly use the sn.exe utility to generate a string name file.
When you have run the Add-In wizard, added your custom code, and tested the Add-In then you are ready to register it. The gacutil.exe program can be used to add an assembly to the GAC. The command is gacutil /i <path\>myaddin.dll where myaddin is the name of your Add-In. (By default the gacutil.exe utility is located in the "C:\Program Files\Microsoft.NET\FrameworkSDK\Bin\gacutil.exe" directory.) Include the complete path information for gacutil.exe and your Add-In. If you browse to the shared assembly directory (see figure 2) then you will be able to determine that your registry has been added to the GAC. Finally you will need to add the registry entries necessary for the Add-in Manager to manage the Add-In.
In early versions of beta 2 this process seems to be a little unreliable. This is to be expected from beta software. Expect refinements in the creation and testing of Add-Ins in release versions of Visual Studio.Net. Return to this column for more information on shared assemblies and building Add-Ins as revisions to VS.NET are made available.
About the Author
Paul Kimmel is a freelance writer for Developer.com and CodeGuru.com. Look for cool Visual Basic.Net topics in his upcoming book "Sams Visual Basic .Net Unleashed".
Paul founded Software Conceptions, Inc. in 1990. Contact Paul Kimmel at email@example.com for help building VB .NET applications or migrating VB6 applications to .NET.
# # #