I wanted to get this blogged until we get an article published on this.  Here's the problem that were recently encountering and what we found, after the fact it all makes sense when you think about.

When using CDO 1.21 and trying to cancel an existing meeting from an organizer's mailbox you find that the cancellation requests remain in the Outbox and are not sent.

The key to determining the root cause of this issue is that the original meeting request was sent out to a Outlook personal distribution list and does not occur if you send the same meeting request to a Exchange distribution list.

So what is the difference when sending to a Outlook personal distribution list, and why would it matter?  In this case we were using the CDO 1.21 from a ESM (Exchange System Manager) install, and not an Outlook install, and were using dynamically generated profiles.  The Personal distribution item is a Outlook object that MAPI and CDO don't specifically know about.

The problem that we are seeing here is related to the contab32 (Outlook Address Book service).  This is the service that Outlook uses to resolve these personal DL's to an email address.  So when we create a profile with ProfileInfo option in CDO logon call this service is not added to the dynamically generated profile. When we try to go and resolve this personal DL to a email address, we fail since we do not have a service loaded capable of resolving this address.  So the mail just sits in the outbox of the organizer's mailbox, unresolved and unsent. 

Secondly you would also experience this same problem without any meeting requests in the mix at all.  You can also reproduce the same problem and actually get a error returned on send.  This is easy to do by composing an email to the same personal DL in Outlook.  Instead of actually sending the email, just save it in the drafts and then use CDO to get the Entry ID and try to send the message.  When CDO tries to send this saved message, using ProfileInfo, the following error is returned:

E_INVALIDARG(80070057)

Again we've run into the limitation that the Outlook Address Book service isn't loaded when we use ProfileInfo with CDO's logon call and dynamically create a profile.  This is "by design" since CDO can't do anything to load this service within the dynamic profile. 

So how do you work around this?

We really have the following options to avoid this issue:

  • One way would be to use a previously (programmatically or through the Profile wizard) created profile that has this contab32 service loaded.  Then when logging on with CDO instead of using the ProfileInfo parameter in Logon call, we specify this profile to logon with.  Hence, when we go to resolve the personal DL, we have the Outlook Address Book service available to CDO.  This of course would require you to run your application on a machine that had Outlook installed to get the contab32 service.  If you are planning to use your CDO code in a service, then this option may not be the best option since the Outlook installed bits are suited very well to being used in a service.
  • Another option, if you are in a Exchange environment, would be to use a Exchange Distribution List instead of a Personal DL.  Here we would have no limitation on using the dynamic or static profiles to logon and send mail or cancel the meeting request.  This is probably the better option if you are looking to use your CDO code in a service-type application.  This option wouldn't require that you have Outlook installed on the machine where this application it running, you could just have ESM installed on this machine to get CDO and MAPI.