次の方法で共有


FYI: Why are MAPI and CDO 1.21 not supported in managed (.NET) code?

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…

  1. 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.
  2. 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.
  3. 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.

Comments

  • Anonymous
    October 03, 2007
    PingBack from http://web-design.dailygeektoy.com/?p=104

  • Anonymous
    October 05, 2007
    For anyone needing CDO 1.21 functionality in a .Net application, I would highly advise them to check out the Redemption library by Dmitry Streblechenko -- specifically the Redemption Data Objects (RDO).  RDO is designed to be a functional replacement for CDO plus has some nice extras.

  • Anonymous
    October 05, 2007
    Observations about the software industry today Mobile E-Mail For Business: How Five Platforms Compare

  • Anonymous
    October 06, 2007
    So Microsoft knows that many (most?) business apps will have a requirement of some sort of connectivity to Exchange data stores, yet after four versions of the framework, we STILL do not have any managed classes in the framework to handle this every day requirement.  How many THOUSANDS of hours of developer productivity have been lost trying to bypass this obvious and unforgivable omission? Utterly Ridiculous.

  • Anonymous
    October 07, 2007
    Sorry you feel so strongly that we have let you down.  I'm not sure you will ever see the .NET Framework ship classes for accessing Exchange.   Exchange APIs are shipped with the product themselves and are updated as the product is updated because they contain business logic specific to that version.  Shipping them in the Framework would take away our ability to update them with the Exchange product updates and would tie them to the Framework instead of the product they are built to work with - seems like a bad idea to me. In Exchange 2007 we have made a HUGE investment in .NET - maybe the biggest of any product group thus far.  A large majority of the new product code for 2007 is C#.  ALL of the new API scenarios (Exchange Web Services, Transport Agents, Powershell, etc.) is geared towards .NET development. Even in Exchange 2003 you do have options - it isn't like you can't write a .NET application that works with Exchange data.  CDOEX provides a robust interface to Exchange.  For remote applications - WebDAV is a decent option although it doesn't do everything, it does many of the basic functions needed for an Exchange application.

  • Anonymous
    October 15, 2007
    Hi, I believe this configuration should be supported, correct me if I'm wrong:

  • C++ unmanaged process calling an inprocess COM-interop'ed .NET code in a DLL.
  • the same C++ unmanaged process using MAPI for some other purpose.
  • Anonymous
    October 15, 2007
    No this wouldn't be supported - we don't support any scenario of CDO 1.21 or MAPI being loaded in the same process as the CLR.

  • Anonymous
    October 15, 2007
    The comment has been removed

  • Anonymous
    October 15, 2007
    In general principle third party APIs aren't supported by Microsoft, you would have to follow up with the vendor to get their support policy. To reiterate my point to the other commenter about adding Exchange APIs to the .NET Framework, it just isn't the place for it at all.  The .NET Framework's class libraries provide classes for doing basic operations - it is not the end-all-be-all for interoperability and is not intended to be.  There are no Sharepoint APIs in the Framework, there are no Biztalk APIs in the Framework, and there are no SQL Management APIs in the Framework.  Just like Exchange APIs - product specific business logic will not end up in the .NET Framework because it needs to be shipped with the product itself and most likely be version specific. Please check out Exchange Web Services for managed code interoperability with Exchange... http://msdn2.microsoft.com/en-us/library/bb402321.aspx

  • Anonymous
    October 15, 2007
    Thanks for the link and thanks for the post - please don't think we are shooting the messenger, info like this is invaluable. I do understand that .Net can't have an API for every external system - but email is far more ubiquitous than Sharepoint, Biztalk or SQL Management.  If I had a dollar for every app that tries to send email...I'd be as rich as your boss.  I guess I think of email more like file system API's or maybe LINQ - common enough to deserve more attention.  Of course, maybe email is too mundane or old fashioned.  

  • Anonymous
    October 15, 2007
    Definitely no hard feelings - this is a good discussion and one of the longest ever on my blog so I'm all for it :) Now if you limit your request to purely sending email, the Framework does have classes for that System.Net.Mail which uses SMTP.  While sending email via SMTP is common and useful enough to incorporate into the Framework, I'm not sure that reading or processing mail is.  I guess the arguement could be made for POP or IMAP classes but that would give you much.  All of the interesting business logic - that is always going to be product specific - is the APIs for Exchange only like CDO 1.21, CDOEX, and Exchange Web Services.

  • Anonymous
    October 16, 2007
    Just a comment on where we're coming from (I work for DEcclestone :-) We use MAPI in our app just to send email right now.  The nice thing about it as opposed to SMTP is that we can (optionally) have the compose email UI available to our app, as well as things like the address book, login validation, etc.  With SMTP we'll have to implement our own UI to allow the user to compose and attach files. We may have to utilize the Outlook object model for cases when we want a UI and SMTP for cases when we want no UI. The nice thing (in theory anyways) about MAPI is that other providers (Notes, etc) could support it and we wouldn't have to have different implementations for each email client.  Some sort of a generic open messaging API for .NET would be a nice feature.

  • Anonymous
    October 16, 2007
    The comment has been removed

  • Anonymous
    November 02, 2007
    The comment has been removed

  • Anonymous
    November 02, 2007
    I assure you we are not coming from two different worlds.  I have spent more time as a software developer outside of Microsoft then I have inside Microsoft.  I'm not the product team.  I don't create the product - I support developers like you who use Exchange APIs.  I know all about the hardships of using .NET with Exchange Server 2000/2003.  You are 100% right that CDOEX is not the answer in that it must run on the Exchange server.  WebDAV is the only remote option for writing .NET code to run remotely against an Exchange 2003 Server.  Please don't assume that I don't understand where you are coming from - it is why I write this blog, continue to post & answer your comments, and do the job I do. Additionally (as I have pointed out before) the product team does listen and they do see this as an area to improve, in Exchange 2007 they have addressed your main concern... "All I require is a simple .NET class (don't care if it is a separate download vs. included in the framework) to let me perform "Outlook like" functions from my programs" ...The answer here is Exchange 2007 Web Services - no download required.  Fully supported in .NET and any other language that can submit formatted text to port 80.

  • Anonymous
    November 05, 2007
    Thanks for the reply, I will look forward to the time that our organization upgrades to Exchange 2007.

  • Anonymous
    November 22, 2007
    So where does this leave Visual Studio Tools for Office? Particularly the ability to write managed code against the Outlook object model? Presumably the VSTO libraries are COM based under the wrappers, but they will still run in-process?

  • Anonymous
    November 23, 2007
    The comment has been removed

  • Anonymous
    November 29, 2007
    So if you need a replacement for CDO 1.21 from a client APP that is not a web app to an Exchange server that could be 200/3/7 or unknown What Then? You can't access the address book or the GAL from a desktop app with webDav - no? (in OL2003) OL2007 has some CDO function built in but not OL2003... If CDO 1.21 is available but not .NET supported that means it is implicit that apps must be dev in unmanaged languages like C++ ? Sending mail is not really the problem it's accessing other object on Exchange servers.

  • Anonymous
    November 29, 2007
    If you are running a desktop application then you can use OOM rather than CDO 1.21 to get to the GAL.  In Outlook 2003 OOM doesn't have the PropertyAccessor which gives you greater access to properties on an item so many developers want to use CDO 1.21.  This isn't an impossibility you just need to do it out of process from your managed code... http://blogs.msdn.com/mstehle/archive/2007/07/27/howto-delete-search-folders-and-interop-with-cdo-1-21-from-managed-net-code.aspx

  • Anonymous
    November 29, 2007
    Oh ! Wonderful but too painful article ! Even it might be truth. Some of us knows how limited Exchange is for the mailbox permissions, so I'm looking for the solution like this (including change the ACLs on the folders):  http://support.microsoft.com/kb/240911 But on this blog you say that, nobody should follow above article anymore, unless use C++/VB6. Could you point me out which of these:  http://support.microsoft.com/kb/813349 support ACL modifications on the mailbox level ?

  • Anonymous
    November 29, 2007
    You can edit the ACLs of folders using WebDAV in Exchange 2000/2003 - fully supported from .NET... http://msdn2.microsoft.com/en-us/library/aa123902.aspx You can use Exchange Web Services in Exchange 2007 SP1... http://msdn2.microsoft.com/en-us/library/bb856574.aspx

  • Anonymous
    November 29, 2007
    I just realized that above you mentioned mailbox permissions not folder permissions.  If you are setting permissions at the mailbox level in Exchange 2000/2003 then you can use CDOEXM or modify the AD objects using ADSI, etc. In Exchange 2007 you can use the Add-ADPermission and Add-MailboxPermission cmdlets.

  • Anonymous
    November 30, 2007
    I thought WebDAV is available only on local server, so remotely it is not available. Maybe I was wrong. And yes, I saw the E2007 SP1 web services, and what that offer :-) And yes,  I meant folder's ACLs in Mailbox.

  • Anonymous
    February 18, 2009
    Certain technologies that predate the .NET Framework are not supported in managed code programming. These

  • Anonymous
    April 03, 2009
    Working with a customer the other day, I went looking for my blog post discussing the fact that MAPI