- Published on
Working with Extended MAPI from .NET
- Authors
-
-
- Name
- David Mohundro
- Bluesky
- @david.mohundro.com
-
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?