提问人:Ishmaeel 提问时间:8/7/2008 最后编辑:Mark BiekIshmaeel 更新时间:8/6/2015 访问量:4293
MAPI 和托管代码体验?[关闭]
MAPI and managed code experiences? [closed]
问:
正式不支持在托管代码中使用 MAPI 函数。显然,MAPI 使用自己的内存管理,它会在托管代码中崩溃和烧毁(请参阅此处和此处))
我想做的就是启动带有主题、正文和一个或多个附件的默认电子邮件客户端。
所以我一直在研究 MAPISendDocuments,它似乎有效。但是我还没有能够鼓起勇气在生产代码中实际使用该函数。
有人经常使用这个功能吗?你有什么恐怖故事吗?
不,我不会shellExecute Outlook.exe with command line arguments for attachments.
缴费灵。附件支持是一项要求,所以 Mailto:解决方案对我来说并不切入。
答:
调用进程。从 Mailto: 协议开始(如下所示)将为您提供基本功能,但不会提供附件。
Process.Start("mailto:[email protected]?subject=TestCode&Body=Test Text");
您可以使用附件路径执行此操作,但此选项仅适用于某些旧版本的 Outlook,例如 98。我认为这是由于潜在的安全风险。
如果有人使用 outlook.exe,它将在 Outlook 2003(和 2007 取决于设置)下发出安全警告。
您应该能够创建一个非托管 DLL,该 DLL 使用 MAPI 执行所需的操作,然后从托管代码调用该 DLL。我不会编写一个直接的 MAPI 包装,而是执行该非托管 DLL 中包含的 MAPI 所需的所有功能的东西。这可能是从托管代码中使用 MAPI 的最安全方法。
还可以使用托管代码支持的 Outlook Redemption;我不确定它是否具有简单的 MAPISendDocuments 替换,但如果您有问题,Dmitry 会很有帮助。
至于“崩溃和烧伤”,这是 MS 支持人员的另一句话,这里
这是大多数情况下会起作用的事情。它会在你写的时候工作。然后,当您测试它时,它就会起作用。当您的客户评估它时,它会起作用。然后,一旦客户部署它 - BAM!那时它会决定开始出现问题。Microsoft不会帮助你,因为我们一开始就告诉你不要这样做。:)
评论
我使用 MAPISendMail 函数和几个内部类来包装其他一些与 MAPI 相关的结构来执行此操作。只要这是唯一的用途,就可以安全地做到这一点,尽管不是微不足道的,因为它需要非常密切地关注各种非托管数据类型以及内存分配/释放和 GC。虽然它仍然不受支持,但我在生产代码中使用它(尽管它尚未发布)。
当我向Matt Stehle询问此事时,我得到的回答是:
我真的不知道有更好的方法来做到这一点,您在这里遇到的任何问题都可能在受支持的场景(即 VB6 或非托管 C++)中重现。只要知道,如果您遇到过一个问题是由从 .NET 调用此函数引起的,我们不会有任何其他建议,然后不要使用 .NET。
使用它并不完全是一件好事,但也不是说有任何其他选项可以从托管代码中实际执行此操作。
有一个单独的帮助程序 EXE,它采用命令行参数(或通过管道连接到其 StandardInput),以执行所需的操作,并从主应用调用它。这会将 MAPI 内容保留在主应用的进程空间之外。好的,您仍在混合 MAPI 和 .NET,但过程非常短。假设 MAPI 和 CLR 开始导致运行时间较长的进程出现问题。
我们使用 Dmitry Streblechenko 精湛的 Redemption Data Objects 库,该库允许我们在 JScript 中编写这样的“填充码”代码并调用它,从而将 CLR 和 MAPI 世界保持在单独的进程中,但以受支持的方式。
@Chris Fournier re.编写非托管 DLL。这不起作用,因为问题在于在同一进程中混合 MAPI 和托管代码。
对于有 MAPI 经验的人来说,与键入这篇文章并阅读响应(无冒犯性)相比,他们编写代码以从非托管代码(阅读:纯 C++)中完全执行您想要的操作所需的时间要少。
你很幸运,你需要的功能是有限的。您只需要一个简单的 C++ 实用工具,即可在命令行上获取所需的参数并发出正确的 MAPI 调用。然后,您可以从托管代码中获取所有这些实用程序,就像执行任何其他进程一样。
HTH型
评论
MAPISendDocuments 已弃用,可能会被删除。 应改用 MAPISendMail。 请参阅简单 MAPI
下面的代码不使用 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);
评论