in

SDT Community Server

SDT Forums, Blogs, Photos server.

Floating Heart

No description is bad.

How to build an Office COM add-in by using Visual C# .NET

http://support.microsoft.com/?kbid=302901

How to build an Office COM add-in by using Visual C# .NET

function loadTOCNode(){}
Article ID : 302901
Last Review : May 11, 2007
Revision : 10.1
This article was previously published under Q302901
var sectionFilter = "type != 'notice' && type != 'securedata' && type != 'querywords'"; var tocArrow = "/library/images/support/kbgraphics/public/en-us/downarrow.gif"; var depthLimit = 10; var depth3Limit = 10; var depth4Limit = 5; var depth5Limit = 3; var tocEntryMinimum = 1; .toc{display: none;}

SUMMARY

loadTOCNode(1, 'summary');
Microsoft Office XP, Microsoft Office 2003, and Microsoft Office 2007 support a uniform design architecture for building application add-ins to enhance and to control Office applications. These add-ins are called Microsoft Component Object Model (COM) add-ins. This step-by-step article discusses Office COM add-ins and describes how to build an Office COM add-in by using Microsoft Visual C# .NET.

Back to the top

The IDTExensibility2 interface

loadTOCNode(2, 'summary'); A COM add-in is an in-process COM server, or ActiveX dynamic link library (DLL), that implements the IDTExensibility2 interface as described in the Microsoft Add-in Designer type library (Msaddndr.dll). All COM add-ins inherit from this interface and must implement each of its five methods.

OnConnection

loadTOCNode(3, 'summary'); The OnConnection event fires whenever the COM add-in is connected. The add-in may be connected on startup, by the end user, or through Automation. If the OnConnection event returns successfully, the add-in is said to be loaded. If an error message is returned, the host application immediately releases its reference to the add-in, and the object is destroyed.

The OnConnection event takes the following four parameters:
Application: A reference to the host application object.
ConnectMode: A constant that specifies how the add-in is connected. The add-in can be connected in the following ways:
ext_cm_AfterStartup: The add-in is started by the end user from the COM Add-ins dialog box.
ext_cm_CommandLine: The add-in is connected from the command line. Note that this does not apply to building COM add-ins for Office applications.
ext_cm_External: The add-in is connected by an external application through Automation. Note that this does not apply to building COM add-ins for Office applications.
ext_cm_Startup: The add-in is started by the host at application startup. This behavior is controlled by a setting in the registry.
AddInInst: A reference to the COMAddIn object that refers to this add-in in the COMAddIns collection for the host application.
Custom: An array of Variant type values that can hold user-defined data.

OnDisconnection

loadTOCNode(3, 'summary'); The OnDisconnection event fires when the COM add-in is disconnected and just before it unloads from memory. The add-in should perform any cleanup of resources in this event, and restore any changes made to the host application.

The OnDisconnection event takes the following two parameters:
RemoveMode: A constant that specifies how the add-in was disconnected. The add-in can be disconnected in the following ways:
ext_dm_HostShutdown: The add-in is disconnected when the host application closes.
ext_dm_UserClosed: The add-in is disconnected by the end user or an Automation controller.
Custom: An array of Variant type values that can hold user-defined data.

OnAddInsUpdate

loadTOCNode(3, 'summary'); The OnAddInsUpdate event fires when the set of registered COM add-ins changes. In other words, whenever a COM add-in is installed or removed from the host application, this event fires.

OnStartupComplete and OnBeginShutdown

loadTOCNode(3, 'summary'); Both the OnStartupComplete method and the OnBeginShutdown method are called when the host application has left or is entering a state in which user interaction should be avoided because the application is busy loading or unloading itself from memory. The OnStartupComplete method is called only if the add-in was connected during startup, and the OnBeginShutdown method is called only if the host disconnects the add-in during shutdown.

Because the user interface for the host application is fully active when these events fire, they may be the only way to perform certain actions that otherwise would be unavailable from the OnConnection event and the OnDisconnection event.

Back to the top

COM add-in registration

loadTOCNode(2, 'summary'); In addition to normal COM registration, a COM add-in needs to register itself with each Office application in which it runs. To register itself with a particular application, the add-in should create a subkey, using its ProgID as the name for the key, under the following location:
HKEY_CURRENT_USER\Software\Microsoft\Office\<OfficeApp>\Addins\<ProgID>
The add-in can provide values at this key location for both a friendly display name and a full description. In addition, the add-in should specify its desired load behavior by using a DWORD value that is named LoadBehavior. This value determines how the add-in is loaded by the host application, and is made up of a combination of the following values:
0 = Disconnect - Is not loaded.
1 = Connected - Is loaded.
2 = Bootload - Load on application startup.
8 = DemandLoad - Load only when requested by user.
16 = ConnectFirstTime - Load only once (on next startup).
The typical value specified is 0x03 (Connected | Bootload).

Add-ins that implement IDTExtensibility2 should also specify a DWORD value called CommandLineSafe to indicate whether the add-ins are safe for operations that do not support a user interface. A value of 0x00 indicates False, and a value of 0x01 indicates True.

Back to the top

How to build a COM add-in by using Visual C# .NET

loadTOCNode(2, 'summary'); As mentioned earlier, an Office COM add-in is an in-process COM server that is activated by an Office application through the COM run-time layer. Therefore, developing a COM add-in in .NET requires that the add-in component be implemented in .NET and then exposed to the COM clients (that is, the Office applications) through the COM interop layer.

To create a COM add-in in Visual C# .NET, follow these steps:
1. In Visual C# .NET, create a Class Library project.
2. Add a reference to the type library that implements IDTExtensibility2. The primary interop assembly for this is already available under the name Extensibility.
3. Add a reference to the Microsoft Office object library. The primary interop assembly for this is already available under the name Office.
4. Create a public class in the class library that implements IDTExtensibility2.
5. After the class library is built, register the library for COM interop. To do this, generate a strong named assembly for this class library and then register it with COM interop. You can use Regasm.exe to register a .NET component for COM interop.
6. Create registry entries so that Office applications can recognize and load the add-in.
You can choose to complete all of these steps, or you can create a .NET project of type Shared Addin. This starts the Extensibility Wizard, which helps you to create a COM add-in in .NET.

The Extensibility Wizard creates a Visual C# .NET class library project along with a Connect class that implements the IDTExtensibility2 interface. The skeleton code that implements the empty members of IDTExtensibility is also generated. This project has references to Extensibility and Office assemblies. The build settings of the project have Register for COM Interop selected. The assembly key (.snk) file is generated and is referenced in the AssemblyKeyfile attribute in Assemblyinfo.vb.

Along with the class library project, the wizard generates a setup project that you can use to deploy the COM add-in on other computers. You may remove this project if desired.

Back to the top

Step-by-step example

loadTOCNode(2, 'summary');
1. On the File menu in Microsoft Visual Studio .NET, click New, and then click Project.
2. In the New Project dialog box, expand Other Projects under Project Types, select Extensibility Projects, and then select the Shared Add-in template.
3. Type MyCOMAddin as the name of the add-in and then click OK.
4. When the Extensibility Wizard appears, follow these steps:
a. On page 1, select Create an Add-in using Visual C#, and then click Next.
b. On page 2, select the following host applications, and then click Next:
Microsoft Word
Microsoft PowerPoint
Microsoft Outlook
Microsoft Excel
Microsoft Access
c. On page 3, provide a name and description for the add-in, and then click Next.

Note The name and the description of the add-in appear in the COM Add-in dialog box in the Office application.

d. On page 4, select all of the available options, and then click Next.
e. Click Finish.
5. On the Project menu, click Add Reference. Click System.Windows.Forms.DLL in the components list, click Select, and then click OK.
6. Add the following to the list of namespaces in the Connect class:
using System.Reflection;
7. Add the following member to the Connect class:
private CommandBarButton MyButton; 
8. Implement the code for the members of IDTExtensibility2 in the Connect class, as follows:
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {
   applicationObject = application;
   addInInstance = addInInst;

   if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
   {
      OnStartupComplete(ref custom);
   }

}

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) {
   if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
   {
      OnBeginShutdown(ref custom);
   }
   applicationObject = null;
}


public void OnAddInsUpdate(ref System.Array custom)
{
}

public void OnStartupComplete(ref System.Array custom)
{
   CommandBars oCommandBars;
   CommandBar oStandardBar;

   try
   {
   oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null);
   }
   catch(Exception)
   {
   // Outlook has the CommandBars collection on the Explorer object.
   object oActiveExplorer;
   oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);
   oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);
   }

   // Set up a custom button on the "Standard" commandbar.
   try
   {
   oStandardBar = oCommandBars["Standard"];        
   }
   catch(Exception)
   {
   // Access names its main toolbar Database.
   oStandardBar = oCommandBars["Database"];      
   }

   // In case the button was not deleted, use the exiting one.
   try
   {
   MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"];
   }
   catch(Exception)
   {
      object omissing = System.Reflection.Missing.Value ;
      MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing);
      MyButton.Caption = "My Custom Button";
      MyButton.Style = MsoButtonStyle.msoButtonCaption;
   }

   // The following items are optional, but recommended. 
   //The Tag property lets you quickly find the control 
   //and helps MSO keep track of it when more than
   //one application window is visible. The property is required
   //by some Office applications and should be provided.
   MyButton.Tag = "My Custom Button";

   // The OnAction property is optional but recommended. 
   //It should be set to the ProgID of the add-in, so that if
   //the add-in is not loaded when a user presses the button,
   //MSO loads the add-in automatically and then raises
   //the Click event for the add-in to handle. 
   MyButton.OnAction = "!<MyCOMAddin.Connect>";

   MyButton.Visible = true;
   MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click);


   object oName = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null);

   // Display a simple message to show which application you started in.
   System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString()   , "MyCOMAddin");
   oStandardBar = null;
   oCommandBars = null;
}

public void OnBeginShutdown(ref System.Array custom)
{
   object omissing = System.Reflection.Missing.Value ;
   System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading.");
   MyButton.Delete(omissing);
   MyButton = null;
}

private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) {
   System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); }
					
9. Build and test the COM add-in. To do this, follow these steps:
a. On the Build menu, click Build Solution. Note that building the COM add-in registers the .NET class with the COM interop.
b. Start one of the Office applications that you selected as host applications for your add-in (for example, Microsoft Word or Microsoft Excel).
c. After the add-in has started, the OnStartupComplete event of the add-in is fired, and you receive a message. Dismiss the message box. Note that the add-in added a new custom button with the caption "My Custom Button" to the standard toolbar.
d. Click My Custom Button. The Click event for the button is handled by the add-in and you receive a message box. Dismiss the message box.
e. Quit the Office application.
f. When you quit the application, the OnBeginShutDown event fires, and you receive a message. Dismiss the message box to end the demonstration.
Published Sep 03 2008, 09:21 AM by wicky
Filed under:

Comments

 

wicky said:

Hello Word Outlook Add-In using C#

weblogs.asp.net/.../93712.aspx

One thing I’d like to play with is extending Outlook through add-ins with C#. It’ll be a good opportunity to learn more about .NET development and the Windows tools. Plus, I can “fix” some of the things that annoy me about Outlook. I’ve been talking to Omar about this too, and hopefully we can collaborate on a few projects. We’ve been sharing a few links back and forth on getting started. It’s a bit hard to find the right information to get started, but it’s out there. I’ve compiled steps below for a “hello world” type Outlook project that I’ll be building off in the future. I hope this will be useful to others trying to get started on developing Outlook add-ins using managed code. Please let me know if I’m missing anything or have errors.

Install Primary Interop Assemblies

.NET can interface with COM code using interop assemblies. You can create these as needed by adding a reference to a COM type library. However, if you do this for the Outlook/Office type libraries, this will lead to strange problems like this. This doesn’t sound like the thing I want to find out about the hard way. The solution is to install “primary interop assemblies” that live in the GAC and will be used instead of custom generated ones. You can download PIAs for Outlook XP here. For Outlook 2003, you can go to Control Panels->Add/Remove programs and customize your installation to add them. Just choose “.NET Programmability” under the various components. They are initially set to install on first use – I don’t know what would actually trigger this. Once these are installed, adding a reference to the COM type libraries will add these “magic” versions instead of generating new versions with strange issues.

Create a Visual Studio.NET project

Create a new Visual Studio.Net project. For the project type, select Other Projects->Extensibility Projects->Shared Add-ins (who would think to look here?). This brings you through a wizard where you can select the language (C#, of course!) and which hosts to support. One cool thing you can do with the Office COM-plugins is support multiple apps with the same plugin, but I’m only interested in Outlook for now. Then, you have the chance to fill in some other random info, and your project is created. The project will have template code that implements the IDTExtensibility2 interface required to create an add-in.

Add references

We need to add references to a couple of things we’ll be using. Right-click References under the add-in project, select “Add Reference”, go to the COM tab, and select Microsoft Outlook 11.0 Object Library (or Outlook 10.0 if you are using Outlook XP). If the PIA stuff worked right, when you select it in the solution explorer, the path in the properties tab should be pointing into the GAC, not into the office folder. Next, select

“Add Reference” again, and add “System.Windows.Forms” from the .NET tab. This will let us do our “Hello World” dialog.

Flesh out code

First, we need to add a member variable. We’ll also change the type of the application object to be the Outlook type (since we’ll only support Outlook):

private Microsoft.Office.Interop.Outlook.Application applicationObject;

private object addInInstance;

private CommandBarButton toolbarButton;

Next, we’ll update OnConnection to cast to the Outlook object type, and add some logic from kb 302901 (why isn’t this in the template if it’s the right thing to do?):

public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)

{    

   applicationObject = (Microsoft.Office.Interop.Outlook.Application)application;

   addInInstance = addInInst;

   if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)

   {

       OnStartupComplete(ref custom);

   }

}

Likewise, we’ll update OnDisconnection according to kb 302901:

public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)

{

   if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)

   {

       OnBeginShutdown(ref custom);

   }

   applicationObject = null;

}

Next, when we’re done loading, we will create a toolbar button. The version in kb 302901 is more complex because it’s generalize to work in apps other than Outlook:

public void OnStartupComplete(ref System.Array custom)

{

   CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars;

   // Create a toolbar button on the standard toolbar that calls ToolbarButton_Click when clicked

   try

   {

        // See if it already exists

        this.toolbarButton = (CommandBarButton)commandBars["Standard"].Controls["Hello"];

   }

   catch(Exception)

   {

       // Create it

       this.toolbarButton = (CommandBarButton)commandBars["Standard"].Controls.Add(1, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);

       this.toolbarButton.Caption = "Hello";

       this.toolbarButton.Style = MsoButtonStyle.msoButtonCaption;

   }

   this.toolbarButton.Tag = "Hello Button";

   this.toolbarButton.OnAction = "!<MyAddin1.Connect>";

   this.toolbarButton.Visible = true;

   this.toolbarButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.OnToolbarButtonClick);

}

On shutdown, we’ll delete our toolbar button:

public void OnBeginShutdown(ref System.Array custom)

{

   this.toolbarButton.Delete(System.Reflection.Missing.Value);

   this.toolbarButton = null;

}

And, we’ll define the action when clicking the button:

private void OnToolbarButtonClick(CommandBarButton cmdBarbutton,ref bool cancel)

{

   System.Windows.Forms.MessageBox.Show("Hello World","My Addin");

}

To test it out, you build the addin project, and then the setup project. Quit Outlook, then right-click the setup project and select “Install”.  When you launch Outlook, a button named “Hello” will show up in the main toolbar. Selecting it will say “Hello World”. You can manage this add-in by going to the COM add-in dialog at Tools->Options->Other->Advanced Options->COM Add-Ins.

What’s missing

There are some steps that need to be taken to install the PIA when installing your add-in. See the steps here. That sample also has a lot of information about signing your plugin, which I’ve ignored so far.

What’s next

Next, I have to learn more about the Outlook object model and how to actually do interesting things. I also need to learn how to debug the add-ins.

Reference

General description of COM Add-Ins: msdn.microsoft.com/.../default.asp

A sample Visual Basic.NET plugin (describes the PIA stuff): msdn.microsoft.com/.../default.asp

KB 302901 (building an Office COM plugin using Visual C#.NET): support.microsoft.com

Niobe, a library for Outlook managed plug-ins (I’m not sure what you get above doing it from scratch, there isn’t much documentation): www.gotdotnet.com/.../workspace.aspx

September 3, 2008 9:25 AM
Copyright SDT, 2006-2009. All rights reserved.