"Mo"
Published on

Working with Extended MAPI from .NET

Authors

Lately, I’ve been doing some work with integrating some of my managed applications with Outlook. There are a lot of code examples and articles out there on using the Outlook COM interop library for tying into Outlook, but be prepared for a lot of security prompts for the user. I understand the reasoning behind those security prompts, but man are they annoying.

You basically have two options at this point if you don’t like the prompts. Extended MAPI or Outlook Redemption. Seriously, those seem to be the only two options available, unless your application is actually an add-in using VSTO. Extended MAPI is essentially the low-level side of Outlook. To program against it, you’re looking at using C/C++ or Delphi, because your only interface is header files. I took a look at it and it is HAIRY. If you are interested in that option, though, check out MAPIEx at the Code Project. It has some great examples of using Extended MAPI and also showed me enough to scare me away from this option. I would love to spend my company’s time and resources learning this and code in C++, but I don’t think they would appreciate that very much.

Okay, next. Outlook Redemption. It is a COM wrapper around the Extended MAPI interface that works great. Dmitry Streblechenko created a lot of safe objects around their Extended MAPI counterparts. You code against the Outlook Interop library (add a COM reference to “Microsoft Outlook 11.0 Object Library”) and tie that in with Redemption. Everyone uses this thing. Just about every newsgroup post, website, etc. that mentions tying into Outlook recommends this library. I guess this is another recommendation.

My only real complaint with Redemption had to be the stupid Fields collection off of just about every Redemption object. For example, let’s look at the Redemption.AddressEntry. It exposes a name, address, and a few other handy properties, but that is about it. If you want to get anything else, you have to use the Fields collection, which takes an Integer and returns an Object. The Fields collection could be compared to a Dictionary object in the .NET Framework. The name is a unique integer that is a lookup to a value. A little annoying but hey, if we have constants, who cares right? Right??? … What do you mean we don’t have any constants? Ohhh, we have to find those out for ourself or buy Outlook Spy! I hate magic numbers!

I was fairly confident that the lookup constants were defined somewhere so I began hunting them down and discovered the MAPITags.h file (mine was at C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include). All of the constants use a macro called PROP_TAGS (see MAPIDefS.h) that takes a ULong propID and a ULong propType. Internally, Outlook uses a multitude of different property types like PT_NULL, PT_LONG, PT_BOOLEAN, etc. The PROP_TAG macro takes the type and a unique lookup. That’s why the Fields dictionary returns an Object: it might be a long or a boolean or a string or an internal Outlook structure. I ended up writing a console application that read in a header file and spit out a list of VB constants. The regular expression I used was \#define\s+?(?<name>[\w|\d]+?)\s+PROP_TAG\(\s?(?<type>[\w\d]+?),\s?(?<id>[\w\d]+?)\).

Anyway, long story short, I’m working with Outlook now and it is really cool. I’m able to, based on a name and my generated VB constants, lookup a property of a contact in my address book. Another programmer and I have been spamming each other testing with meeting appointments and emails ever since. Fun, eh?