Accessing Microsoft® Outlook® and Microsoft® Exchange
MAPI Store events in .NET: C#, VB, C++

Add-in Express™
Free tools and components


MAPI Store Accessor

The MAPI Store Accessor is a free .NET component that helps you with accessing low-level features provided by Extended MAPI in Microsoft® Windows® Forms applications as well as in .NET-based COM add-ins for Microsoft Outlook in Microsoft® Visual Studio® .NET 2005, 2008 and 2010.

You can think of both Microsoft Outlook and Microsoft Exchange as feature-rich wrappers over the MAPI subsystem. When developing Microsoft Outlook and Exchange, Microsoft decided to use some of the MAPI features and abandoned others. As a result, you do not get some events or event details when the user deletes the last item in a Microsoft Outlook folder, changes the item in an Microsoft Outlook Explorer window, deletes more than 16 items at once, and so on, and so forth.

MAPI Store events

Among Microsoft Outlook events, the NewMail event is the most used and the most unpleasant one. With the Accessor, you get this event at first hand. The component allows you to subscribe to any or all MAPI notifications in either synchronous or asynchronous mode. The list of notifications includes: OnNewMail, OnObjectCopied, OnObjectCreated, OnObjectDeleted, OnObjectModified, OnObjectMoved, OnExtendedNotification and OnSearchComplete. In a typical scenario, you use the MAPI Store Accessor to connect to the current Microsoft Outlook profile. To connect to another profile, you specify the profile name and user password in the Initialize method.

The MAPI Store Accessor works with Microsoft Outlook 2010 32-bit, 2007, 2003, 2002 (XP) and 2000.

Download MAPI Store Accessor

Accesing Extended MAPI properties and events in .NET

MAPI Store Accessor FAQ

1. What Outlook versions are supported by MAPI Store Accessor?

MAPI Store Accessor supports accessing MAPI properties in Outlook 2000-2007 as well as in the 32-bit edition of Outlook 2010.

2. Is there a version of MAPI Accessor supporting Outlook 2010 64-bit?

No, there's no such version and we do not plan to add support for Outlook 2010 64-bit in the near future. If your add-in is loaded in Outlook 2010 64-bit, we suggest that you use the PropertyAccessor Interface introduced in Outlook 2007; for more info please see PropertyAccessor Object. In case you run into restrictions of that interface (see Don't stumble over a stone working with the PropertyAccessor and StorageItem classes in Outlook 2007), you will have to dwell into Extended MAPI, see Outlook 2010 MAPI Reference and Outlook 2007 MAPI Reference.

If none of the options suggested above will work for your project, an alternative would be to use the Outlook Redemption 5.0 library. Redemption is a MAPI wrapper implemented via COM interfaces available for use with any programming language. It duplicates and extends the functionality offered in the Outlook Object Model and CDO (Collaboration Data Objects) and supports installations of 64-bit Outlook. You can purchase a license here.

3. How can I use the MAPI Store Accessor in my COM add-in?

In Add-in Express based add-ins, you can drag and drop the MAPI Store Accessor onto the add-in module. Before using the MAPI Store Accessor in the code, you should invoke the Initialize method of the component. The best place is the AddinStartupComplete event handler of the add-in module.

4. How can I use the MAPI Store Accessor in my WinForms application?

See the previous answer. By creating the component in your code, you can use the MAPI Store Accessor in console applications, services, etc.

5. What programming languages are supported?

The MAPI Store Accessor works in all popular languages of Visual Studio .NET 2005, 2008 and 2010: C#, Microsoft Visual Basic®, C++.

6. How can I find out what Initialize overload version I need?

Initialize(false). Indicates that the component works with Microsoft Outlook running. The component connects to the default profile and shares the existing session.

Initialize(true). Indicates that the component works as a standalone MAPI client. The component connects to the default profile and creates a new session.

Initialize(string profile, string password). Indicates that the component works as a standalone MAPI client. The components connects to the profile specified by the first parameter.

7. How can I subscribe to the MAPI Store Accessor events?

Tick the events you need in the drop-down list of the Properties window. Then create appropriate event handlers.

Also, you can opt to asynchronous event handling. By setting the Interval property, you can choose a time interval at which you want to get notified about events occurred.

8. How can I disconnect from the MAPI subsystem?

Use the LogOff method that releases resources and disconnects from MAPI. This method is also called in the component's finalizer.

9. How can I get the value of a MAPI property?

Use the GetProperties or GetProperty method.

GetProperties(object outlookObject, array of ADXMAPIPropertyTag tags)

GetProperty(object outlookObject, ADXMAPIPropertyTag tag)

To increase the performance of your application, use the GetProperties method that returns more than one property value at a time. For large property values (the limit depends on the provider), use the GetProperty method. For instance, to get the PR_BODY value, use the GetProperty method. If you use the GetProperties method on PR_BODY, you can get NULL (Nothing in VB.NET) if the property value exceeds the limit.

OutlookObject must be one of the following types:

  • Outlook item-level type (MailItem, TaskItem, etc)
  • AddressEntry
  • AddressList
  • Attachment
  • ExchangeDistributionList
  • ExchangeUser
  • Folder
  • Recipient
  • Store

Tags and tag are MAPI property tags defined in the ADXMAPIPropertyTag enumeration.

10. How can I set the value of a MAPI property?

Use the SetProperties or SetProperty method.

SetProperties(object outlookObject, array of ADXMAPIPropertyTag tags, array of object values)

SetProperty(object outlookObject, ADXMAPIPropertyTag tag, object value)

For the purpose of increasing the performance of your application, use the SetProperties method that allows setting several property values at a time. For large property values, use the SetProperty method. If you use the SetProperties method on PR_BODY, it will return an HRESULT value representing an appropriate error if the property value exceeds the limit which depends on the provider.

Values or value are values to be set. The values should always be of the Object type.

11. How can I delete certain properties?

Use the DeleteProperties or DeleteProperty method.

12. How can I find out the result of the GET , SET and DELETE properties?

SetProperties, SetProperty, DeleteProperties, DeleteProperty

The rule of thumb: always check returned arrays for null.

The rule of thumb: if a method return zero (SET, DELETE properties methods), the invocation was successful. A non-zero value (or array value) indicates that the operation failed.

If SetProperties returns NULL (Nothing in VB.NET), the operation failed. Check out the LastError property for additional information (if available).

If SetProperties returns a non-empty array, you should check every member of this array. If the operation was successful, the appropriate array member contains zero.

GetProperties, GetProperty

If GetProperties returns NULL (Nothing in VB.NET), the invocation wasn’t successful. Check out the LastError property for additional information (if available).

If GetProperties returns a non-empty array, you should check every member of the array. If the appropriate member is equal to zero, the property cannot be retrieved. Try to use GetProperty instead.

If GetProperty returns NULL, the property cannot be retrieved (the property may not exist) or an error has occurred. In this case, check out the LastError property for additional information (if available).

13. How can I get additional info when an error occurs?

Check the LastError property of the ADXMAPIAccessor object. Note that this property always returns information related to the last error or NULL (Nothing in VB.NET). To distinguish errors, check the time when the error occurred.

14. How can I deploy my add-ins /applications?

You should include the following prerequisite into your setup project: Visual C++ Runtime Libraries (x86) SP1. Install it and find it in the Prerequisites dialog of your setup project.

15. How can I get the current profile name?

See the CurrentProfileName property of the MAPI Store Accessor.

16. Where can I get additional info about the MAPI Store Accessor?

The installation package includes the class reference.

17. Where can I get code samples for the MAPI Store Accessor?

The installation package contains demo projects in C# and VB.NET.

18. Is it a true .NET component?

One part of the module is written using unmanaged code and the other using managed code. Please note that Microsoft don't recommend using MAPI in managed code. That's why the unmanaged part of the MAPI Store Accessor works with MAPI while the managed part constitutes a .NET component that is a wrapper over the unmanaged code.

19. What versions of the .NET runtime does the MAPI Store Accessor support?

.NET 2.0

20. What versions of Visual Studio does the MAPI Store Accessor support?

Visual Studio 2005 and 2008, Standard and Professional editions.

21. How can I recognize the type of the returned object?

The following table shows type conversion:

MAPI

.NET

PT_APPTIME

System.DateTime

PT_BINARY

System.Byte [ ]

PT_BOOLEAN

System.Boolean

PT_CLSID

System.Guid

PT_CURRENCY

System.Int64

PT_DOUBLE

System.Double

PT_ERROR

Null

PT_FLOAT

System.Single

PT_LONG

System.UInt32

PT_LONGLONG

System::Int64

PT_NULL

Null

PT_OBJECT

System.Int32 or System.Byte [ ]

PT_SHORT

System.Int16

PT_STRING8

System.String

PT_SYSTIME

System.DateTime

PT_UNSPECIFIED

Null

PT_UNICODE

System.String

For example, if you want to get a property such as PR_BODY, you should expect that it would be System.String.