官方不支持在托管代码中使用MAPI函数。显然,MAPI使用自己的内存管理,并在托管代码中崩溃和烧毁(请参阅here和here)
我想要做的就是启动默认电子邮件客户端,主题,正文,和一个或多个附件。
所以我一直在研究MAPISendDocuments,它似乎有效。但是我没有勇气在生产代码中实际使用该功能。
有没有人经常使用这个功能?你有恐怖故事吗?
PS。不,我不会用附件的命令行参数shellExecute Outlook.exe。
PPS。附件支持是要求,因此Mailto:解决方案不会为我删除它。
答案 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