c# - 从 C# 在 Windows 桌面电子邮件客户端中打开新电子邮件窗口

标签 c# .net email outlook mapi

我正在尝试使用下面的方法打开一个填充的电子邮件窗口,该方法是从一个单独的 STA 线程调用的。

    private void SendMailMessage(object ignore)
    {
        MAPIHelperInterop.MapiMessage message = new MAPIHelperInterop.MapiMessage();

        using(RecipientCollection.InteropRecipientCollection interopRecipients
            = fRecipientCollection.GetInteropRepresentation())
        {
            message.Subject = fSubject;
            message.NoteText = fBody;

            message.Recipients = interopRecipients.Handle;
            message.RecipientCount = fRecipientCollection.Count;

            // Check if we need to add attachments
            if(fFiles.Count > 0)
            {
                // Add attachments
                message.Files = AllocateFileAttachments(out message.FileCount);
            }

            // Signal the creating thread (make the remaining code async)
            fManualResetEvent.Set();

            int error = MAPIHelperInterop.MAPISendMailW(IntPtr.Zero, IntPtr.Zero, message, 0x8, 0);

            if(fFiles.Count > 0)
            {
                // Deallocate the files
                DeallocateFileAttachments(message);
            }

            // Check for error
            if(error != SUCCESS_SUCCESS)
            {
                LogMAPIError(error);
            }
        }
  }

我一直在用 Outlook 对此进行测试,我不断收到错误代码 2 (MAPI_E_FAILURE),并且在 Outlook 中没有任何可见的事情发生(最终它应该适用于任何邮件客户端,但 Outlook 是主要用例,因此是一个可扩展的解决方案对于 Outlook 将是很好的第一步)。仅当我以管理员身份启动 Outlook 或在运行代码时关闭 Outlook 时,它才有效。我尝试使用 Outlook 句柄和不同的标志组合调用 MAPISendMailW,但这也不起作用。

我发现最接近我的问题的是这个 https://social.msdn.microsoft.com/Forums/office/en-US/63e9f5b2-f5f2-4cf8-bdc2-ca1fad88ebe5/problem-with-outlook-and-mapisendmail-returns-mapiefailure-when-outlook-is-running?forum=outlookdev .为了遵循建议的解决方案,尝试在单独的 AppDomain 中运行 SendMailMessage 方法,如下所示:

     public void ShowDialog()
    {
        Evidence e = new Evidence();
        e.AddHostEvidence(new Zone(SecurityZone.MyComputer));           
        AppDomain appDomain = AppDomain.CreateDomain("Outlook Launcher", e);            
        appDomain.DoCallBack(SendMailMessage);                     
    }

如果我使用“SecurityZone.MyComputer”,那么我会得到与以前相同的错误,如果我使用任何其他 SecurityZone,我会收到此错误消息:“请求类型为‘System.Security.Permissions.ReflectionPermission,mscorlib, Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089' 失败。”也许这不是他们在上面的帖子中建议的,但这是我能想到的任何事情。

感谢您的帮助。

最佳答案

我过去使用过 MAPI,要跨不同的 Outlook 版本正常工作可能会很痛苦。

一个非常简单的解决方法是使用 mailto 链接。优点是它会自动与不同的邮件客户端一起工作。

 Process.Start("mailto:hello@test.com&subject=This is the subject&body=This is the body");

这将打开您的默认邮件客户端,并填写主题和正文。

关于c# - 从 C# 在 Windows 桌面电子邮件客户端中打开新电子邮件窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43367830/

相关文章:

c# - 如何让 MetroLog 开始登录 Windows 8.1 应用商店应用程序?

.net - ReadConsoleOutputCharacter 不适用于德语变音符号

Phpmailer 不在同一域上发送电子邮件

c# - 使用选定文件打开 Windows 资源管理器(或焦点,如果存在)的代码

iphone - 如何在我的 iOS 应用程序中读取和呈现电子邮件帐户的电子邮件收件箱?

c# - -ERR 超过登录限制 15 分钟。减少对 POP3 服务器的请求频率

javascript - 如何使用 CsQuery 删除 html 内容中的所有脚本标签

c# - 在自定义控件上使用命令

c# - 为什么反编译的程序集看起来与用于编译它的 C# 不完全一样?

c# - Winforms异步加载大数据?