MAPI and managed code experiences? [closed]

一世执手 提交于 2019-11-29 09:24:42

Have a separate helper EXE that takes command-line params (or pipe to its StandardInput) that does what is required and call that from your main app. This keeps the MAPI stuff outside of your main app's process space. OK, you're still mixing MAPI and .NET but in a very short-lived process. The assumption is that MAPI and the CLR start causing issues with longer-running processes.

We use Dmitry Streblechenko's superb Redemption Data Objects library which allows us to write such "shim" code in JScript and invoke that, which keeps the CLR and MAPI worlds in separate processes, but in a supported fashion.

@Chris Fournier re. writing an unmanaged DLL. This won't work because the issue is mixing MAPI and managed code in the same process.

André van Schoubroeck

MAPISendDocuments is deprecated and might be removed. You should use MAPISendMail instead. See Simple MAPI

Calling process.Start on the Mailto: protocol (as shown below) will give you basic functionality but not attachments.

Process.Start("mailto:name@domain.com?subject=TestCode&Body=Test Text");

You can do this approach with attachment paths but this option only works with some old version of outlook such as 98. I assume this is due to the potential securty risk.

If anyone does use outlook.exe it will give security warnings under outlook 2003 (and 2007 Dependant on settings).

You should be able to make an unmanaged DLL that performs the operations you want using MAPI, and then invoke that DLL from your managed code. I wouldn't write a straight MAPI wrapper, but something that performs all of the functionality you require of MAPI contained in that unmanaged DLL. That would probably be the safest way to use MAPI from managed code.

You could also use Outlook Redemption, which is supported from managed code; I'm not immediately sure if it has a simple MAPISendDocuments replacement, but Dmitry's helpful if you have questions.

As for "crashes and burns", here's another quote from an MS support guy, here

It's the sort of thing that'll mostly work. It'll work while you're writing it. Then it'll work while you're testing it. It'll work while your customer is evaluating it. Then as soon as the customer deploys it - BAM! That's when it'll decide to start having problems. And Microsoft ain't gonna help you with it, since we told you not to do it in the first place. :)

I have done this using the MAPISendMail function and several internal classes to wrap some of the other MAPI related structures. As long as this is the only use, it is possible although not trivial to do safely as it requires a very close attention to the various unmanaged data types and memory allocation/deallocation and GC. While it still isn't supported, I am using this in production code (although it hasn't shipped yet).

When I asked Matt Stehle about this, the response I received was:

I really don't know of a much better way to do this and any issues you ran into here would be probably reproducible in a supported scenario (i.e. VB6 or unmanaged C++). Just know that if you ever ran into a scenario were an issue was caused specifically by this function being called from .NET that we wouldn't have any other recommendation for you then to not use .NET.

Not exactly a blessing on using it, but also not saying there are any other options to actually do this from managed code.

The following code doesn't use MAPI as such, but it does open the "Compose Mail" window with arbitrary attachments.

(actually, it's entirely untested but I dug it up in an application that I believe to have worked)

using Microsoft.Office;
using Microsoft.Office.Core;

...

Outlook.Application outlook = new Outlook.Application();
Outlook.MailItem mail = (Outlook.MailItem) outlook.CreateItem(Outlook.OlItemType.olMailItem);

mail.BodyFormat = Outlook.OlBodyFormat.olFormatRichText;
mail.HTMLBody = "stuff";
mail.Subject = "more stuff";
string file = File.ReadAllBytes(...);
mail.Attachments.Add(file, Outlook.OlAttachmentType.olByValue, 1, file)

mail.Display(false);

For someone experienced with MAPI, it would take them less time to crank out the code to do exactly what you want from unmanaged code (read: plain C++) than typing this post and reading the response (no offense).

You're lucky the functionality you need is limited. All you need is a simple C++ utility to take the params you need on the command-line and issue the right MAPI calls. Then, you all this utility from your managed code just as you'd to execute any other process.

HTH

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!