MAPI和托管代码体验?

官方不支持从托管代码中使用MAPI函数。显然,MAPI使用自己的内存管理,并在托管代码中崩溃并烧毁(请参阅 here and here

All I want to do is launch the default e-mail client with subject, body, AND one or more attachments.

所以我一直在寻找 MAPISendDocuments ,它似乎工作。但是我一直没能鼓足勇气去实际使用生产代码中的功能。

有没有人用过这个功能?你有什么恐怖故事吗?

PS。不,我不会使用附件的命令行参数shellExecute Outlook.exe。

PPS. Attachment support is a requirement , so Mailto: solutions do not cut it for me.

0
谢谢你的问题和联系!找出有关MAPI /托管代码的东西帮助拯救我一些时间开发。
额外 作者 SkullDuggerT,

8 答案

调用过程。从 Mailto:协议开始(如下所示)会给你基本的功能,但不会附件。

Process.Start("mailto:[email protected]?subject=TestCode&Body=Test Text");

您可以使用附件路径来实现此方法,但此选项仅适用于某些旧版本的Outlook,如98.我认为这是由于潜在的安全风险。

如果有人使用outlook.exe,它会在Outlook 2003(和2007依赖于设置)下发出安全警告。

0
额外

下面的代码不会像这样使用MAPI,但它会打开带有任意附件的“撰写邮件”窗口。

(实际上,它完全没有经过测试,但是我在一个我认为可以工作的应用程序中挖掘出来)

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);
0
额外

我已经使用MAPISendMail函数和几个内部类来包装一些其他MAPI相关结构。只要这是唯一的使用方式,虽然安全性并不差,但它需要非常密切关注各种非托管数据类型和内存分配/释放和GC。虽然它仍然不受支持,但我在生产代码中使用了它(尽管它尚未发货)。

当我向Matt Stehle询问这件事时,我收到的回复是:

我真的不知道有更好的方法可以做到这一点,并且您遇到的任何问题都可能在支持的方案(即VB6或非托管C ++)中重现。只要知道,如果你碰到过一个场景,那么一个问题是由.NET调用的这个函数引起的,我们不会有任何其他推荐给你,那么就不要使用.NET。

不完全是使用它的祝福,也不是说有任何其他选项可以从托管代码实际执行此操作。

0
额外

有一个单独的帮助程序EXE,它执行所需的命令行参数(或管道到其StandardInput),并从您的主应用程序中调用该参数。这将MAPI内容保留在主应用程序进程空间之外。好的,您仍在混合使用MAPI和.NET,但时间很短。假设是MAPI和CLR开始导致长时间运行的进程出现问题。

我们使用Dmitry Streblechenko的精湛的 Redemption Data Objects 库,它允许我们在JScript中编写这样的“shim”代码和调用它,这将CLR和MAPI世界保留在单独的进程中,但是采用受支持的方式。

@Chris Fournier re。编写一个非托管DLL。这是行不通的,因为问题是在同一进程中混合使用MAPI和托管代码 。

0
额外

您也可以使用 Outlook Redemption ,这是从托管代码支持的;我不能立即确定它是否有简单的MAPISendDocuments替换,但如果您有问题,德米特里会很有帮助。

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

大部分工作都是这样的。它会在你写作的时候工作。然后它会在你测试它时工作。它会在你的客户评估它的时候工作。然后,只要客户部署它 - BAM!那是什么时候它会决定开始有问题。而微软不会帮助你,因为我们告诉过你不要这样做。 :)
0
额外
我认为海报是指管理的应用程序将大量的重量放在MAPI上。只要在用户请求中调用MAPISendMail不会导致相同的问题。
额外 作者 Yuhong Bao,

对于有MAPI经验的人来说,与输入这篇文章并阅读回复(没有违规)相比,他们需要更少的时间来开发代码,以便从非托管代码中完全实现您想要的功能(阅读:纯C ++)。

你很幸运,你需要的功能是有限的。您只需要一个简单的C ++实用程序即可在命令行上获取所需的参数,并发出正确的MAPI调用。然后,从您的托管代码中获取所有此实用程序,就像执行任何其他进程一样。

HTH

0
额外
任何机会,你可以启动代码并发布在这里?
额外 作者 JoshL,

您应该能够制作一个非托管DLL,使用MAPI执行所需的操作,然后从托管代码中调用该DLL。我不会写一个直接的MAPI包装器,而是执行所需的包含在该非托管DLL中的MAPI的所有功能。这可能是从托管代码使用MAPI最安全的方法。

0
额外

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

0
额外