The issue of using MAPI or (most commonly) CDO 1.21 in managed (.NET) code is one that comes back to us a lot on the Messaging Developer Support team. Both the messaging technologies in question and the .NET framework have been around for many years at this point. As well have the KB articles that state the supportability of Outlook and Exchange APIs in managed code. There are three main contributors to steady stream of cases we see – even today – where customers are using MAPI and CDO 1.21 in managed code…
- More and more Windows development is done using managed code these days. The .NET Framework has taken hold – especially in the consulting industry – and most custom software consultants use the .NET Framework over C++ or VB6. Many times the decision to use .NET in a solution is an assumption from the beginning and not something evaluated based on the requirements of the application. It can be easy forget in today’s environment that you can still write unmanaged code and there are situations where you might have to.
- Outlook and Exchange development is a niche – many ISVs and consultants have to get into messaging development to accomplish a small part of a larger application. In other words, they don’t do this every day like I do. These developers simply know they need to accomplish a task be it checking an inbox, creating an appointment, or sending an email. They search the web and find a sample that seems to work for them and move on.
- CDO 1.21 *appears* to work just fine in managed code. Before entering the ranks of Microsoft and finding myself in this cube thinking about Exchange all day, I too, was a consultant in the wild. I found myself in the situation above – I was writing a .NET Windows Service and needed to check an Inbox. I converted some old VB6 code I had to VB.NET and moved on. Everything worked fine through testing but in production we had this nagging memory leak and an occasional Access Violation which we could never quite figure out. Turns out that many of the problems with using CDO 1.21 or MAPI in managed code didn’t show up until our application was under stress or running for a while because they are mainly memory management issues. From a usability perspective, there are no initial red flags or awkwardness to warn you that you are doing something you shouldn’t.
Okay, I’ve heard that before so why exactly is using MAPI or CDO 1.21 not supported in managed code?
MAPI has its own memory management model that conflicts with and is incompatible with the .NET runtime. This the primary reason that MAPI and CDO 1.21 are not supported running in a .NET process. The common symptoms you will see are seemingly random Access Violations and very often memory leaks (especially with CDO 1.21). There is no methodology for avoiding or managing these symptoms by using interop libraries or managing references in a particular fashion in your .NET code – it just won’t work.
The trap is that CDO 1.21 and .NET can “appear” to work and you can get pretty far in your dev cycle before you run into problems. Many times we see this come up in soon after a solution is released to production, in late cycle performance testing, or in a pilot program. Opening a critical case with Microsoft when you have end users complaining of crashes or project managers short on budget is not a good time to find out that your solution is unsupportable.
Take a look at Patrick’s article on what “unsupported” means. He uses MAPI and .NET as an example in this article for reason #4 that something could be deemed unsupported by Microsoft…
“It has known problems…We KNOW this is a problem, so we don’t support it.”
Fine, I won’t use .NET and MAPI or CDO 1.21 in the same process but I still need to write this application – now what?
The simple answer is you either need to not use .NET or not use MAPI or CDO 1.21. So how do you make that decision?
First let’s look at your business requirements to determine where we need to compromise. As I mentioned above a lot of time the decision to write an application in .NET is made long before in depth design has been done and even more frequently the interaction with Exchange is a minimal part of the overall solution. If you are locked into .NET then you can look into alternative APIs that are supported in managed code.
In the pre-Exchange 2007 world, the only supported APIs for managed code from Outlook and Exchange are Outlook Object Model, WebDAV, and CDOEX. Each of these has their limitations:
Outlook Object Model simply automates the Outlook.EXE process and is not supported to run from a service application (Windows Services and ASP.NET applications should not use OOM)
WebDAV is a protocol not an object model and has a steep learning curve (it also has limits on its support for calendaring)
CDOEX is built on top of ExOLEDB which is only intended to be used (and is only supported) on the Exchange server itself – not remotely.
The second thing to consider is why you needed to use MAPI or CDO 1.21 in the first place. MAPI provides a very raw view of the message store without much business logic so you might want to use that to work with item properties or hidden items not available to the other APIs. CDO 1.21 provides a hefty amount of business logic for working with appointments and meetings. Without any noticeable problems upfront when you try to use CDO 1.21 from .NET code, it might seem worth the risk given the options above. If you really feel that CDO 1.21 or MAPI is your best option based on the business requirements of what your application must do then by all means use CDO 1.21 – just plan to use it *out of process* from your .NET code.