MAPI 和托管代码体验?[关闭]

MAPI and managed code experiences? [closed]

提问人:Ishmaeel 提问时间:8/7/2008 最后编辑:Mark BiekIshmaeel 更新时间:8/6/2015 访问量:4293

问:


想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。

8年前关闭。

正式不支持在托管代码中使用 MAPI 函数。显然,MAPI 使用自己的内存管理,它会在托管代码中崩溃和烧毁(请参阅此处和此处)

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

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

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

不,我不会shellExecute Outlook.exe with command line arguments for attachments.

缴费灵。附件支持是一项要求,所以 Mailto:解决方案对我来说并不切入。

.net 电子邮件 pinvoke mapi

评论

1赞 SkullDuggerT 10/30/2008
感谢您的问题和链接!了解 MAPI/托管代码有助于节省一些开发时间。

答:

2赞 John 8/7/2008 #1

调用进程。从 Mailto: 协议开始(如下所示)将为您提供基本功能,但不会提供附件。

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

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

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

1赞 Chris 8/21/2008 #2

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

1赞 Dan Mitchell 8/27/2008 #3

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

至于“崩溃和烧伤”,这是 MS 支持人员的另一句话,这里

这是大多数情况下会起作用的事情。它会在你写的时候工作。然后,当您测试它时,它就会起作用。当您的客户评估它时,它会起作用。然后,一旦客户部署它 - BAM!那时它会决定开始出现问题。Microsoft不会帮助你,因为我们一开始就告诉你不要这样做。:)

评论

0赞 Yuhong Bao 9/15/2011
我认为海报指的是托管应用程序对 MAPI 施加了大量负载。仅根据用户请求调用 MAPISendMail 不太可能导致相同的问题。
1赞 Scott Dorman 8/31/2008 #4

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

当我向Matt Stehle询问此事时,我得到的回答是:

我真的不知道有更好的方法来做到这一点,您在这里遇到的任何问题都可能在受支持的场景(即 VB6 或非托管 C++)中重现。只要知道,如果您遇到过一个问题是由从 .NET 调用此函数引起的,我们不会有任何其他建议,然后不要使用 .NET。

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

8赞 Duncan Smart 9/2/2008 #5

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

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

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

-2赞 Ash 4/4/2009 #6

对于有 MAPI 经验的人来说,与键入这篇文章并阅读响应(无冒犯性)相比,他们编写代码以从非托管代码(阅读:纯 C++)中完全执行您想要的操作所需的时间要少。

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

HTH型

评论

4赞 JoshL 11/17/2010
你有没有机会把代码写出来并发布在这里?
2赞 André van Schoubroeck 10/12/2009 #7

MAPISendDocuments 已弃用,可能会被删除。 应改用 MAPISendMail。 请参阅简单 MAPI

0赞 Roman Starkov 12/10/2010 #8

下面的代码不使用 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);