12

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

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

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

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

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

聚苯乙烯。附件支持是一项要求,因此 Mailto: 解决方案不适合我。

4

8 回答 8

8

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

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

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

于 2008-09-01T20:26:46.720 回答
2

在Mailto: 协议上调用 process.Start (如下所示)将为您提供基本功能,但不提供附件。

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

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

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

于 2008-08-07T11:16:11.987 回答
2

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

于 2009-10-12T14:51:58.337 回答
1

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

于 2008-08-20T20:01:35.723 回答
1

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

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

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

于 2008-08-27T15:26:23.767 回答
1

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

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

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

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

于 2008-08-31T00:43:06.763 回答
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);
于 2010-12-10T11:58:19.327 回答
-2

对于有 MAPI 经验的人来说,与输入这篇文章并阅读响应(无意冒犯)相比,他们花费更少的时间来编写代码以从非托管代码(阅读:纯 C++)中完全按照您的意愿行事。

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

高温高压

于 2009-04-04T05:46:25.163 回答