繁体   English   中英

通过Outlook API发送邮件-Outlook快速关闭

[英]Sending mail via Outlook API - Outlook closes to fast

我写了一堂课,通过Outlook自动发送电子邮件。 除了生成邮件,将邮件放到“外发”文件夹,然后关闭Outlook外,其他所有情况都很好。 关闭是如此之快,以至于我下次启动Outlook时就发送了邮件。

这是我的代码:

public class MyMail
{
    private const double WaitingForSending = 30.0;

    #region Local variables
    public bool SSL_Encryption = true;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> Address = null;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> CC = null;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> BCC = null;
    public System.Collections.Generic.List<string> AttachmentFileName = null;
    public string Body = "";
    public string Subject = "";
    #endregion


    public void SendMail()
    {
        double Waited = .0;
        string fAddress = string.Empty;

        if (this.Address == null) { return; }
        Microsoft.Office.Interop.Outlook.Application OL = new Microsoft.Office.Interop.Outlook.Application();

        Microsoft.Office.Interop.Outlook.MailItem Mail = (Microsoft.Office.Interop.Outlook.MailItem)OL.CreateItem(OlItemType.olMailItem);
        Mail.Subject = this.Subject;
        if (this.Address != null) { foreach (System.Net.Mail.MailAddress MA in this.Address) { fAddress += MA.Address + "; "; } Mail.To = fAddress; fAddress = string.Empty; }
        if (this.CC != null) { foreach (System.Net.Mail.MailAddress MA in this.CC) { fAddress += MA.Address + "; "; } Mail.CC = fAddress; fAddress = string.Empty; }
        if (this.BCC != null) { foreach (System.Net.Mail.MailAddress MA in this.BCC) { fAddress += MA.Address + "; "; } Mail.BCC = fAddress; fAddress = string.Empty; }
        Mail.Body = this.Body;
        if (this.AttachmentFileName != null) { foreach (string Att in this.AttachmentFileName) { if (System.IO.File.Exists(Att)) { Mail.Attachments.Add(Att, Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing); } } }
        Mail.Display(false);

        try
        {
            Mail.Send();
        } catch (System.Exception ex) { throw ex; }

        /*
        while (!Mail.Sent && Waited < WaitingForSending)
        {
            System.Threading.Thread.Sleep(500);
            Waited += 0.5;
        }
        */
    }
}

我评论说“等待循环”不起作用,因为Outlook正在关闭Mail.Send()函数。

有人知道吗,如何让Outlook等待邮件发送完毕?

一月的问候

最后一个浏览器或检查器关闭时,Outlook将立即关闭。 为避免这种情况,请确保显示了资源管理器或检查器,或者至少持有对这些对象之一的引用(它们不必可见)。 可以从MailItem.GetInspectorMAPIFolder.GetExplorer检索检查器。

您可能还想使用Namespace.SendAndRecive发送消息。 请记住, SendAndRecive是异步的,因此您将需要等待SyncObject.SyncEnd事件触发(届时您可以安全地释放资源管理器或检查器并关闭Outlook)。 可以从Namespace.SyncObjects集合中检索SyncObject。

我现在找到了另一个解决方案。 请找到随附的有效解决方案:

    public static class MAPIOutlook
{
    public static OL.Application GetOutlook(out bool StillRunning)
    {
        OL.Application OLApp = null;
        OL.NameSpace nameSpace = null;

        if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
        {
            StillRunning = true;
            try
            {
                OLApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application;
            }
            catch {
                KillOutlook();
                OLApp = new OL.Application();
                nameSpace = OLApp.GetNamespace("MAPI");
                nameSpace.Logon("", "", System.Reflection.Missing.Value, System.Reflection.Missing.Value);
            }
        }
        else
        {
            StillRunning = false;
            OLApp = new OL.Application();
            nameSpace = OLApp.GetNamespace("MAPI");
            nameSpace.Logon("", "", System.Reflection.Missing.Value, System.Reflection.Missing.Value);
        }

        return OLApp;
    }


    public static void KillOutlook()
    {
        foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("OUTLOOK")) { p.Kill(); }
    }

    public static void SendMailAdv(string[] To, string[] CC, string[] BCC, string Subject, string Body, string[] Attachment)
    {
        bool StillRunning = false;
        OL.Application OlApp = GetOutlook(out StillRunning);
        OL.NameSpace NS = OlApp.GetNamespace("MAPI");
        OL.MAPIFolder MFold = NS.GetDefaultFolder(OL.OlDefaultFolders.olFolderOutbox);
        OL.MailItem MI = (OL.MailItem)OlApp.CreateItem(OL.OlItemType.olMailItem);
        OL.Recipients oReci = MI.Recipients;

        foreach(string str in To)
        {
            OL.Recipient Rec = MI.Recipients.Add(str);
            Rec.Type = (int)OL.OlMailRecipientType.olTo;
        }

        foreach (string str in CC)
        {
            OL.Recipient Rec = MI.Recipients.Add(str);
            Rec.Type = (int)OL.OlMailRecipientType.olCC;
        }

        foreach (string str in To)
        {
            OL.Recipient Rec = MI.Recipients.Add(str);
            Rec.Type = (int)OL.OlMailRecipientType.olBCC;
        }

        MI.Subject = Subject;
        MI.Body = Body;

        foreach(string str in Attachment)
        {
            if (System.IO.File.Exists(str.Trim()))
            {
                MI.Attachments.Add(str.Trim(), OL.OlAttachmentType.olByValue, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
            }
        }

        int nOutItems = MFold.Items.Count;

        MI.Send();

        while(nOutItems != MFold.Items.Count)
        {
            System.Threading.Thread.Sleep(250);
        }

        if (!StillRunning)
        {
            OlApp.Application.Quit();
            OlApp.Quit();
            KillOutlook();
        }
    }
}

首先,我会遵循此处列出的Dmitry的建议。

我还注意到,在调用MailItem类的Send方法之前,您会显示一个检查器窗口。 这不是必需的,可能会导致您当前看到的行为。 需要承认,所有Outlook对象都是在方法范围内声明的,这将方法的寿命限制了下来。

public class MyMail
{
    private const double WaitingForSending = 30.0;

    #region Local variables
    public bool SSL_Encryption = true;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> Address = null;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> CC = null;
    public System.Collections.Generic.List<System.Net.Mail.MailAddress> BCC = null;
    public System.Collections.Generic.List<string> AttachmentFileName = null;
    public string Body = "";
    public string Subject = "";
    #endregion

    private Microsoft.Office.Interop.Outlook.Application OL;
    private Microsoft.Office.Interop.Outlook.MailItem Mail;

    public void SendMail()
    {
        double Waited = .0;
        string fAddress = string.Empty;

        if (this.Address == null) { return; }
        OL = new Microsoft.Office.Interop.Outlook.Application();

        Mail = (Microsoft.Office.Interop.Outlook.MailItem)OL.CreateItem(OlItemType.olMailItem);
        Mail.Subject = this.Subject;
        if (this.Address != null) { foreach (System.Net.Mail.MailAddress MA in this.Address) { fAddress += MA.Address + "; "; } Mail.To = fAddress; fAddress = string.Empty; }
        if (this.CC != null) { foreach (System.Net.Mail.MailAddress MA in this.CC) { fAddress += MA.Address + "; "; } Mail.CC = fAddress; fAddress = string.Empty; }
        if (this.BCC != null) { foreach (System.Net.Mail.MailAddress MA in this.BCC) { fAddress += MA.Address + "; "; } Mail.BCC = fAddress; fAddress = string.Empty; }
        Mail.Body = this.Body;
        if (this.AttachmentFileName != null) { foreach (string Att in this.AttachmentFileName) { if (System.IO.File.Exists(Att)) { Mail.Attachments.Add(Att, Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing); } } }
        // the following method is not required for sending emails
        // Mail.Display(false);

        try
        {
            Mail.Send();
        } catch (System.Exception ex) { throw ex; }           
    }
}

确保成功发送邮件的最佳方法是处理“已发送邮件”文件夹中的ItemAdd事件。 将一个或多个项目添加到指定的集合时将触发该事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM