MAPI和托管代码体验?

时间:2008-08-07 07:56:24

标签: .net email pinvoke mapi

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

我想要做的就是启动默认电子邮件客户端,主题,正文,和一个或多个附件

所以我一直在研究MAPISendDocuments,它似乎有效。但是我没有勇气在生产代码中实际使用该功能。

有没有人经常使用这个功能?你有恐怖故事吗?

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

PPS。附件支持是要求,因此Mailto:解决方案不会为我删除它。

8 个答案:

答案 0 :(得分:7)

有一个单独的帮助程序EXE,它接受命令行参数(或管道到其StandardInput)执行所需操作并从主应用程序调用它。这使MAPI内容远离主应用程序的进程空间。好吧,你仍然在混合MAPI和.NET,但是在一个非常短暂的过程中。假设MAPI和CLR开始引起更长时间运行的问题。

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

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

答案 1 :(得分:2)

不推荐使用MAPISendDocuments,可能会将其删除。 您应该使用MAPISendMail。 见Simple MAPI

答案 2 :(得分:1)

调用流程。启动Mailto: protocol(如下所示)将为您提供基本功能,但不提供附件。

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

您还可以使用托管代码支持的Outlook Redemption;我不能立即确定它是否有一个简单的MAPISendDocuments替换,但是如果你有问题,Dmitry会很有帮助。

关于“崩溃和烧伤”,这是MS支持人员的另一个引用,here

  

这是一种主要起作用的东西。在你写作的时候它会起作用。然后它会在你测试时工作。它会在您的客户评估它时起作用。然后,一旦客户部署它 - BAM!那时它决定开始遇到问题。微软并不会帮助你,因为我们告诉你不要首先这样做。 :)

答案 5 :(得分:1)

我使用MAPISendMail函数和几个内部类来完成此操作,以包装一些其他MAPI相关结构。只要这是唯一的用途,就可以安全地进行,因为它需要非常密切关注各种非托管数据类型和内存分配/释放和GC。虽然它仍然不受支持,但我在生产代码中使用它(虽然它还没有发货)。

当我问Matt Stehle时,我收到的回复是:

  

我真的不知道有更好的方法来执行此操作,您遇到的任何问题都可能在受支持的方案(即VB6或非托管C ++)中重现。只要知道如果遇到一个场景,问题是由.NET调用的这个函数特别引起的,那么我们就没有任何其他的建议就可以不使用.NET。

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

答案 6 :(得分: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);

答案 7 :(得分:-3)

对于有MAPI经验的人来说,他们需要更少的时间来编写代码来完成你想要的非托管代码(读取:普通C ++),而不是输入这个帖子并阅读响应(没有冒犯)。

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

HTH