【问题标题】:Generate Multiple Mails with Outlook使用 Outlook 生成多封邮件
【发布时间】:2017-06-07 13:50:03
【问题描述】:

我想使用 Outlook 向多个客户发送电子邮件。为此,我的程序中有一个方法可以迭代收件人、编写消息正文并将第一条消息显示为预览。

这是该方法的简化版本:

public void CreateMails(List<InfoMailRecipient> recipients)
{
    Microsoft.Office.Interop.Outlook.Application outlook = new Microsoft.Office.Interop.Outlook.Application();
    foreach (InfoMailRecipient recipient in recipients)
    {
        MailItem mail = outlook.CreateItem(OlItemType.olMailItem);
        mail.SentOnBehalfOfName = "Sending User";
        mail.BCC = recipient.EMailAddress;

        mail.Subject = "TEST";
        mail.BodyFormat = OlBodyFormat.olFormatHTML;
        mail.HTMLBody = "<html><body>test</body></html>";
        mail.Display(true);
    }
}

当显示 Outlook 消息窗口时,无论我是关闭窗口还是单击“发送”,只要创建下一个MailItem,我就会得到一个异常“RPC 服务器不可用”。显然是因为 Outlook 已关闭。我发现当我删除线时

mail.Display(true);

只需致电.Send();,所有消息都会正确发送。但随后 Outlook 保持打开状态。即使我在foreach 循环之后调用.Quit()

如何正确处理这个 Outlook 实例?

更新 1 - 手动 GC 调用

public void CreateMails(List<InfoMailRecipient> recipients)
{
    Microsoft.Office.Interop.Outlook.Application outlook = new Microsoft.Office.Interop.Outlook.Application();
    foreach (InfoMailRecipient recipient in recipients)
    {
        MailItem mail = outlook.CreateItem(OlItemType.olMailItem);
        mail.SentOnBehalfOfName = "Sending User";
        mail.BCC = recipient.EMailAddress;

        mail.Subject = "TEST";
        mail.BodyFormat = OlBodyFormat.olFormatHTML;
        mail.HTMLBody = "<html><body>test</body></html>";
        mail.Send();
    }
    outlook.Quit();
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

Outlook 继续运行。

【问题讨论】:

  • 每个收件人都收到完全相同的消息吗?
  • 不,消息应该是个性化的
  • 您能否尝试删除 Display 调用,添加对 Quit 的调用,然后添加对 GC.Collect() 和 GC.WaitForPendingFinalizers() 的调用。如果您随后退出此功能,Outlook 会关闭吗?
  • 很遗憾没有效果。
  • 你能用你尝试的第二次代码尝试更新帖子吗?只是为了展示已经尝试过和尚未尝试过的内容?

标签: c# email outlook office-interop


【解决方案1】:

这似乎有效 - 您能否告诉我们它是否也适用于您?

    public static void Main(string[] args)
    {
        CreateMails(new List<string>() {"emailaddresshere"});
        Console.WriteLine("finished");
        Console.ReadLine();
    }

    public static void CreateMails(List<string> recipients)
    {
        Microsoft.Office.Interop.Outlook.Application outlook = new Microsoft.Office.Interop.Outlook.Application();
        foreach (string recipient in recipients)
        {
            MailItem mail = outlook.CreateItem(OlItemType.olMailItem);
            mail.SentOnBehalfOfName = "Sending User";
            mail.BCC = recipient;

            mail.Subject = "TEST";
            mail.BodyFormat = OlBodyFormat.olFormatPlain;
            mail.HTMLBody = "Hello";
            mail.Send();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(mail); // key change
        }
        GC.Collect();
        GC.Collect();
        GC.WaitForPendingFinalizers();
        outlook.Application.Quit();
        outlook.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(outlook); // key change
        outlook = null;
        GC.Collect();
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }

还可以阅读https://ausdotnet.wordpress.com/category/technical/com-interop/How to close outlook after automating it in c#

【讨论】:

  • 确实如此!谢谢你。它似乎已经可以与outlook.Quit(); Marshal.ReleaseComObject(outlook);
  • 好消息!
  • 有时会,有时不会……我最终释放了对象并终止了进程……没关系……
  • 告诉我你使用的最终代码(dotnetfiddle.net),我可以检查你是否遗漏了什么......
  • 由于它在测试应用程序中仍然运行良好,我对此进行了深入研究,我认为我用这个简化版本欺骗了自己。因为在实际方法中,我另外创建了一个附件。而且我猜那个对象仍然在引用前景。我现在也发布了该对象,现在它似乎即使经过多次测试也能运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 2021-07-08
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 2021-09-06
  • 1970-01-01
相关资源
最近更新 更多