I use something like this, the code is from a C# addin template for Outlook
2007, but you can just ignore the Office 2007 specific stuff. It's a partial
copy of the code in my Connect.cs class:
namespace CSAddinTemplate
{
using System;
using Extensibility;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using Microsoft.Vbe.Interop.Forms;
using stdole;
using System.Drawing;
using System.Text;
using System.Diagnostics;
/// <summary>
/// The object for implementing an Add-in.
/// </summary>
/// <see also class='IDTExtensibility2' />
[GuidAttribute("B0B9C466-B680-49B6-B7E2-3EC9C9F46334"),
ProgId("CSAddinTemplate.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2,
Office.IRibbonExtensibility, Office.ICustomTaskPaneConsumer,
Outlook.FormRegionStartup
{
#region Module_level_declarations
public static string m_ProgID = "";
// start of COM objects
private object applicationObject = null;
public Outlook.Application m_Outlook = null;
private Outlook.NameSpace m_NameSpace = null;
private Office.COMAddIn addInInstance = null;
// Event-aware references to Explorers collection & ActiveExplorer
private Outlook.Explorers m_Explorers = null;
private Outlook.ExplorersClass m_ExplorersClass = null;
private Outlook.Explorer m_Explorer = null;
private Outlook.ExplorerClass m_ExplorerClass = null;
// Event-aware references to Inspectors collection & ActiveInspector
private Outlook.Inspectors m_InspectorClasss = null;
private Outlook.InspectorsClass m_InspectorClasssClass = null;
private Outlook.Inspector m_Inspector = null;
private Outlook.InspectorClass m_InspectorClass = null;
// end of COM objects
// Explorer Wrapper Collection
private System.Collections.SortedList m_ExplWrap = null;
// Inspector Wrapper Collection
private System.Collections.SortedList m_InspWrap = null;
private int m_WrapperID = 0;
private int m_OutlookVersion = 0;
//Initialization flags
private bool m_Teardown = false;
private bool m_Init = false;
//Ribbon UI object
private Office.IRibbonUI m_Ribbon;
//CTP objects
private Office.ICTPFactory m_CTP;
private Office.CustomTaskPane CTP;
private const string CTP_PROGID = "CSAddinTemplate.EmailTaskPane";
private const string CTP_EXPL_PROGID =
"CSAddinTemplate.CustomTaskPane";
private const string CTP_TITLE = "CS Config";
private const string CTP_EXPL_TITLE = "CS WEB";
// Form Region declarations
// use the value in the <name> tag in the Region XML
private const string TIME_TRAVEL_FORM_REGION = "TimeTravel";
private Outlook.FormRegion m_FormRegion;
private TimeTravelFormRegionWrapper m_RegionWrap;
#endregion
/// <summary>
/// Implements the constructor for the Add-in object.
/// Place your initialization code within this method.
/// </summary>
public Connect()
{
}
#region Startup_Shutdown
/// <summary>
/// Implements the OnConnection method of the IDTExtensibility2
interface.
/// Receives notification that the Add-in is being loaded.
/// </summary>
/// <param term='application'>
/// Root object of the host application.
/// </param>
/// <param term='connectMode'>
/// Describes how the Add-in is being loaded.
/// </param>
/// <param term='addInInst'>
/// Object representing this Add-in.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array custom)
{
applicationObject = application;
System.Windows.Forms.Application.EnableVisualStyles();
try
{
addInInstance = (Office.COMAddIn)addInInst;
}
catch
{
addInInstance = null;
}
if (addInInstance != null)
{
//set module level reference to COMAddIn object
try
{
m_Outlook = (Outlook.Application)application;
m_NameSpace = m_Outlook.GetNamespace("MAPI");
//event-aware reference to Explorers collection
//use NewExplorer event to watch for UI creation
m_Explorers = m_Outlook.Explorers;
try
{
//put ProgID in a module level variable
m_ProgID = addInInstance.ProgId;
//addInInstance.Object = Me
addInInstance.GetType().InvokeMember("Object",BindingFlags.Public
| BindingFlags.SetProperty, null, addInInst, new object[] { this });
m_Teardown = false;
//Are we starting with UI?
if (m_Explorers.Count > 0)
{
m_Explorer = m_Outlook.Explorers[1];
//we have UI - initialize base class
InitHandler();
if (m_Init == true)
{
// allot space initially for 15 open
Explorers at a time
m_ExplWrap = new
System.Collections.SortedList(15);
OutExpl adder = new OutExpl();
m_WrapperID = adder.AddExpl(m_Explorer,
m_WrapperID, ref m_ExplWrap);
adder = null;
// allot space initially for 15 open
Inspectors at a time
m_InspWrap = new
System.Collections.SortedList(15);
}
m_InspectorClasss = m_Outlook.Inspectors;
m_Outlook.OptionsPagesAdd += new
Microsoft.Office.Interop.Outlook.ApplicationEvents_11_OptionsPagesAddEventHandler(m_objOutlook_OptionsPagesAdd);
m_NameSpace.OptionsPagesAdd += new
Microsoft.Office.Interop.Outlook.NameSpaceEvents_OptionsPagesAddEventHandler(m_NameSpace_OptionsPagesAdd);
m_Explorers.NewExplorer += new
Microsoft.Office.Interop.Outlook.ExplorersEvents_NewExplorerEventHandler(m_Explorers_NewExplorer);
m_ExplorerClass =
(Outlook.ExplorerClass)m_Explorer;
m_ExplorerClass.ExplorerEvents_Event_Close +=
new
Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(m_Explorer_Close);
m_InspectorClasss.NewInspector += new
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(m_InspectorClasss_NewInspector);
}
else
{
//do nothing
//monitor Explorers collection (in this module)
//if NewExplorer event is raised then we have UI
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
TearDown();
}
}
else TearDown();
}
/// <summary>
/// Implements the OnDisconnection method of the
IDTExtensibility2 interface.
/// Receives notification that the Add-in is being unloaded.
/// </summary>
/// <param term='disconnectMode'>
/// Describes how the Add-in is being unloaded.
/// </param>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
if (m_Teardown == false) TearDown();
}
/// <summary>
/// Implements the OnAddInsUpdate method of the
IDTExtensibility2 interface.
/// Receives notification that the collection of Add-ins has
changed.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnAddInsUpdate(ref System.Array custom)
{
}
/// <summary>
/// Implements the OnStartupComplete method of the
IDTExtensibility2 interface.
/// Receives notification that the host application has
completed loading.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnStartupComplete(ref System.Array custom)
{
// uncomment for an Explorer task pane
//if (m_CTP != null)
//{
// try
// {
// CTP = m_CTP.CreateCTP(CTP_EXPL_PROGID, CTP_EXPL_TITLE,
m_Explorer);
// CTP.DockPositionRestrict =
Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
// CTP.DockPosition =
Office.MsoCTPDockPosition.msoCTPDockPositionRight;
// CTP.Visible = true;
// }
// catch (Exception ex)
// {
// MessageBox.Show(ex.Message);
// }
//}
}
/// <summary>
/// Implements the OnBeginShutdown method of the
IDTExtensibility2 interface.
/// Receives notification that the host application is being
unloaded.
/// </summary>
/// <param term='custom'>
/// Array of parameters that are host application specific.
/// </param>
/// <seealso class='IDTExtensibility2' />
public void OnBeginShutdown(ref System.Array custom)
{
}
#endregion
#region utility_procedures
public void InitHandler()
{
string sVerLeft2 = "";
string sVersion = "";
//********************************************************
sVersion = m_Outlook.Version;
sVerLeft2 = sVersion.Substring(0, 2);
switch( sVerLeft2)
{
case "10":
m_OutlookVersion = 10;
break;
case "11":
m_OutlookVersion = 11;
break;
case "12":
m_OutlookVersion = 12;
break;
default:
if ((sVerLeft2.Substring(0 , 1)) == "9")
{
m_OutlookVersion = 9;
}
else
{
m_OutlookVersion = 0;
}
break;
}
//set initialization flag
m_Init = true;
}
private void TearDown()
{
if (m_Teardown == false)
{
try
{
if (m_ExplWrap != null)
{
m_ExplWrap.Clear();
m_ExplWrap = null;
}
if (m_InspWrap != null)
{
m_InspWrap.Clear();
m_InspWrap = null;
}
// remove the event handlers
if (m_Explorers != null)
{
m_Explorers.NewExplorer -= new
Microsoft.Office.Interop.Outlook.ExplorersEvents_NewExplorerEventHandler(m_Explorers_NewExplorer);
}
if (m_InspectorClasss != null)
{
m_InspectorClasss.NewInspector -= new
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(m_InspectorClasss_NewInspector);
}
//release Ribbon reference
m_Ribbon = null;
//release CTP references
m_CTP = null;
CTP = null;
//release form region reference
m_FormRegion = null;
//release reference to Outlook objects
if (m_Explorer != null) m_Explorer = null;
if (m_Explorers != null) m_Explorers = null;
if (m_InspectorClasss != null) m_InspectorClasss = null;
if (m_Inspector != null) m_Inspector = null;
if (m_ExplorersClass != null) m_ExplorersClass = null;
if (m_ExplorerClass != null) m_ExplorerClass = null;
if (m_InspectorClasssClass != null) m_InspectorClasssClass =
null;
if (m_InspectorClass != null) m_InspectorClass = null;
if (m_NameSpace != null) m_NameSpace = null;
if (m_Outlook != null) m_Outlook = null;
if (applicationObject != null) applicationObject = null;
if (addInInstance != null) addInInstance = null;
m_Teardown = true;
m_Init = false;
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion
#region explorer_related_events
// NewExplorer event will be raised if there is UI
private void
m_Explorers_NewExplorer(Microsoft.Office.Interop.Outlook.Explorer Explorer)
{
//assign ActiveExplorer
m_Explorer = Explorer;
if (m_Init == false)
{
//we didn't have UI before - initialize add-in objects
InitHandler();
}
if (m_Init == true)
{
OutExpl adder = new OutExpl();
m_WrapperID = adder.AddExpl(Explorer, m_WrapperID, ref
m_ExplWrap);
adder = null;
}
}
// Monitor Explorer_Close to see when UI "disappears"
private void m_Explorer_Close()
{
//release current reference
m_Explorer = null;
try
{
m_Explorer = m_Outlook.ActiveExplorer();
}
catch
{
if (m_Outlook.Inspectors.Count == 0)
{
//release add-in objects
if (m_Teardown == false) TearDown();
}
}
}
#endregion
#region inspector_related_events
private void
m_InspectorClasss_NewInspector(Microsoft.Office.Interop.Outlook.Inspector
Inspector)
{
//No handling of Inspectors for Notes, they are brain dead
// set up to get the Class property of the item in the Inspector
object item = Inspector.CurrentItem;
Type _type;
_type = item.GetType();
object[] _args = new Object[] { }; // dummy argument array
Outlook.OlObjectClass _class = Outlook.OlObjectClass.olNote;
try // try to get the Class using reflection
{
_class = (Outlook.OlObjectClass)_type.InvokeMember("Class",
BindingFlags.Public | BindingFlags.GetField |
BindingFlags.GetProperty,
null, item, _args);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
_class = Outlook.OlObjectClass.olNote;
}
if (_class != Outlook.OlObjectClass.olNote)
{
m_Inspector = Inspector;
try
{
m_InspectorClass = (Outlook.InspectorClass)m_Inspector;
m_InspectorClass.InspectorEvents_Event_Close += new
Microsoft.Office.Interop.Outlook.InspectorEvents_CloseEventHandler(molInspector_Close);
OutInsp adder = new OutInsp();
switch (_class)
{
case Outlook.OlObjectClass.olMail:
CTP = m_CTP.CreateCTP(CTP_PROGID, CTP_TITLE,
Inspector);
CTP.DockPositionRestrict =
Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
CTP.DockPosition =
Office.MsoCTPDockPosition.msoCTPDockPositionRight;
CTP.Visible = false;
break;
case Outlook.OlObjectClass.olAppointment:
m_RegionWrap = new TimeTravelFormRegionWrapper();
break;
default:
{
break;
}
}
// m_RegionWrap and m_Ribbon are dummies, filled in when
Ribbon_OnLoad and BeforeFormRegionShow fire
m_WrapperID = adder.AddInsp(Inspector, m_WrapperID, _class,
ref m_InspWrap, CTP, m_RegionWrap, m_Ribbon);
adder = null;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void molInspector_Close()
{
m_Inspector = null;
try
{
m_Inspector = m_Outlook.ActiveInspector();
}
catch
{
if (m_Inspector == null)
{
if (m_Outlook.Explorers.Count == 0)
{
if (m_Teardown == false)
{
TearDown();
}
}
}
}
}
#endregion