Introduction to the Collaboration Data Objects
The Outlook object model is complemented by another object model called Collaboration Data Objects (CDO). This section briefly discusses this object model and the reasons you might have to use it.CDO provides some functionality unavailable in the Outlook object model. CDO works against the underlying data that Outlook is connected to rather than working against UI elements specific to Outlook. CDO exposes some properties of folders and Outlook items that the Outlook object model does not expose. CDO also provides methods unavailable in the Outlook object model. For example:
- CDO lets you delete an Outlook item permanently without first routing it to the Deleted Items folder, whereas Outlook always routes Outlook items you delete to the Deleted Items folder.
- CDO lets you programmatically show the Select Names dialog that can be used to choose recipients for an e-mail message.
- CDO lets you read and write several properties that are either not available in the Outlook object model or are read-only in the Outlook object model.
The connection between the Outlook object model and CDO is that every Outlook item is in an information store represented in Outlook by a root folder in Outlook's Folder List view. An information store can be an Exchange mailbox on a server or a local PST file. Every information store is identified by a StoreID. Within that information store, an Outlook item is identified by an EntryID. So if you can get the StoreID and EntryID associated with an Outlook item via the Outlook object model, you can write CDO code to get to that same Outlook item using the StoreID and EntryID.Before we show some code that illustrates navigating from an Outlook item to a CDO item, let's first consider how to add a reference to the CDO object model. Given that you have a project in Visual Studio, right-click the References folder in the Solution Explorer and choose Add Reference. In the Add Reference dialog shown in Figure 9-13, click the COM tab and select the component Microsoft CDO 1.21 Library. Then click the OK button.
Figure 9-13. Adding a reference to CDO.

Listing 9-4. Getting from an Outlook MailItem to a CDO Message Object
Figure 9-14 shows a diagram of the objects in the CDO object model. This book does not cover the CDO object model in any additional depth.
using System;
using System.Windows.Forms;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookAddin1
{
public partial class ThisApplication
{
Outlook.NameSpace nameSpace;
MAPI.Session mapiSession;
Outlook.Inspectors inspectors;
private void ThisApplication_Startup(object sender, EventArgs e)
{
nameSpace = this.Session;
mapiSession = new MAPI.Session();
mapiSession.Logon(missing, missing, false, false,
missing, missing, missing);
inspectors = this.Inspectors;
inspectors.NewInspector += new
Outlook.InspectorsEvents_NewInspectorEventHandler(
Inspectors_NewInspector);
}
private void ThisApplication_Shutdown(object sender, EventArgs e)
{
mapiSession.Logoff();
}
MAPI.Message GetMessageFromOutlookItem(object outlookItem)
{
object entryID = GetPropertyHelper(outlookItem, "EntryID");
object parentFolder = GetPropertyHelper(outlookItem, "Parent");
object storeID = GetPropertyHelper(parentFolder, "StoreID");
return (MAPI.Message)mapiSession.GetMessage(entryID, storeID);
}
object GetOutlookItemFromMessage(MAPI.Message message)
{
string entryID = (string)message.ID;
string storeID = (string)message.StoreID;
return nameSpace.GetItemFromID(entryID, storeID);
}
private object GetPropertyHelper(object targetObject,
string propertyName)
{
return targetObject.GetType().InvokeMember(propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.GetProperty,
null,
targetObject,
null,
System.Globalization.CultureInfo.CurrentCulture);
}
void Inspectors_NewInspector(Outlook.Inspector inspector)
{
object inspectedItem = inspector.CurrentItem;
MAPI.Message message = GetMessageFromOutlookItem(inspectedItem);
MessageBox.Show(String.Format(
"message.Subject={0}", message.Subject));
object outlookItem = GetOutlookItemFromMessage(message);
MessageBox.Show(String.Format(
"outlookItem.Subject={0}",
GetPropertyHelper(outlookItem, "Subject")));
}
#region VSTO Designer generated code
private void InternalStartup()
{
this.Startup += new EventHandler(ThisApplication_Startup);
this.Shutdown += new EventHandler(ThisApplication_Shutdown);
}
#endregion
}
}