Getting 2 C# Outlook addins to talk together
The Outlook Object Model (OOM) exposes the COMAddins collections of COMAddin object which can be used by Outlook plugins to communicate together. The communication needs to be done through a COM interface. C# and the .NET framework makes it very easy.
You first need to make a ComVisible interface which the caller will use to communicate with the callee. The sample we will work with is a simple class that will call System.Windows.Forms.MessageBox.
using System;
using System.Runtime.InteropServices;
namespace MessageBox
{
[ComVisible(true)]
public interface IMessageBox
{
void MessageBox(String msg);
}
}
Next you need to make the callee addin. This addin can be made using VTSO or without it. Addin Express would work too. The callee of course needs to implement IMessageBox interface.
[ComVisible(true)]
[ComDefaultInterface(typeof(IMessageBox))]
public partial class ThisAddIn : IMessageBox
{
public void MessageBox(String msg)
{
System.Windows.Forms.MessageBox.Show("MessageBox() call: " + msg);
}
protected override object RequestComAddInAutomationService()
{
return this;
}
/* ... snip ... */
}
This is not the full code of the addin. I have removed the boring part generated by VTSO.
There are 2 important things to notice in the above code. The first is the ComDefaultInterface attribute, which defines which default interface is exposed to COM by the addin. This is important because the ThisAddin class derives from a non-COM-visible class. The page on the NonCOMVisibleBaseClass Managed Debugging Assistant (MDA) has the information on why this is important.
The next important thing is the implementation of the RequestComAddinAutomationService, which return an instance of the COM class to the caller. This is part of the communication protocol between addins. You can make this method return any instance of a COM visible objects. We’ve used the addin class itself to keep things simple.
Finally, the caller code amounts to accessing the COMAddins collection and finding the right object inside it to get the interface.
object msgBoxID = "MessageBox.Addin";
Office.COMAddIns addins = null;
Office.COMAddIn msgBox = null;
IMessageBox imsgBox = null;
try
{
addins = Application.COMAddIns;
msgBox = addins.Item(ref msgBoxID);
imsgBox = (IMessageBox)msgBox.Object;
// Actually use the other addin interface.
imsgBox.MessageBox("Hello, this is a selection change.");
}
finally
{
if (addins != null) Marshal.ReleaseComObject(addins);
if (msgBox != null) Marshal.ReleaseComObject(msgBox);
}
This code is pretty straightforward. The 2 important things to notice are the ref object parameter to the COMAddin.Item method and the fact that you need to use the ProgID of the callee addin when searching inside the COMAddins collection. I put emphasis on this because I lost some time trying to find the ProgID of the IMessageBox interface. The ProgID of the addin, when using VTSO, is usually the name of the assembly.
This research was done in the context of the development of the Echotracker although it is still way too early to say what feature will be built on top of that.
