[SOLVED] Outlook schließt, bevor die Mail versandt wurde



  • Hallo,

    ich möchte über den Outlook-Interop eine mail versenden.

    Folgenden Code nutze ich dafür:

    public static class MAPIOutlook
        {
            private static bool Sent = false;
    
            public static OL.Application GetOutlook(out bool StillRunning)
            {
                OL.Application OLApp = null;
    
                if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
                {
                    StillRunning = true;
                    try
                    {
                        return System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application;
                    }
                    catch { KillOutlook(); return GetOutlook(out StillRunning); }
                }
                else
                {
                    StillRunning = false;
                    OLApp = new OL.Application();
                    OL.NameSpace nameSpace = OLApp.GetNamespace("MAPI");
                    nameSpace.Logon("", "", System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                    nameSpace = null;
                    return OLApp;
                }
            }
    
            public static void KillOutlook()
            {
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("OUTLOOK")) { p.Kill(); }
            }
    
            public static void SendMail(string Receiver, string Subject, string Body)
            {
                bool StillRunning = false;
                OL.Application OlApp = GetOutlook(out StillRunning);
                OL.NameSpace NS = OlApp.GetNamespace("MAPI");
    
                OL.MailItem MI = OlApp.CreateItem(OL.OlItemType.olMailItem);
                MI.To = Receiver;
                MI.Subject = Subject;
                MI.Body = Body;
    
                OL.SyncObject SO = NS.SyncObjects[1];
                SO.SyncEnd += SO_SyncEnd;
                Sent = false;
                MI.Send();
    
                if (!StillRunning)
                {
                    OlApp.Application.Quit();
                    OlApp.Quit();
                    KillOutlook();
                }
            }
    
            private static void SO_SyncEnd()
            {
                Sent = true;
            }
        }
    

    Leider schließt Outlook, bevor die Mail versandt wurde. Hat jemand eine Idee wie ich heraus bekomme, ob die Mail gesendet wurde? Bitte, der Hinweis "irgendwie nen Inspector zu definieren" nutzt mir nichts. Um ehrlich zu sein habe ich das schon oft gelesen, aber noch nie eine funktionierendes Beispiel dafür gefunden. Im "Gesendet" Ordner nach der mail zu suchen ist für mich auch keine Option, denn hier werden oft mails mit dem gleichen Betreff gesendet. Und der Hash MailItem.EntryID ist "null", bevor die mail gesendet wurde.

    Hat irgend jemand ein funktionierendes Beispiel, einen Event den man nutzen könnte (der Event MailItem.Send wird BEIM SENDEN ausgeführt, nicht nach dem senden - auch hier gibt es im Internet sehr viele falsche "Lösungen"). Einen Inspector über MailItem.GetInspector zu referenzieren ist kein Problem... aber was man weiter damit machen soll, wird stets verschwiegen.

    Vielen Dank und Gruß,
    CJens



  • Hi,

    hab die Antwort gefunden.

    public static class MAPIOutlook
        {
            private static bool Sent = false;
    
            public static OL.Application GetOutlook(out bool StillRunning)
            {
                OL.Application OLApp = null;
    
                if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
                {
                    StillRunning = true;
                    try
                    {
                        return System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application;
                    }
                    catch { KillOutlook(); return GetOutlook(out StillRunning); }
                }
                else
                {
                    StillRunning = false;
                    OLApp = new OL.Application();
                    OL.NameSpace nameSpace = OLApp.GetNamespace("MAPI");
                    nameSpace.Logon("", "", System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                    nameSpace = null;
                    return OLApp;
                }
            }
    
            public static void KillOutlook()
            {
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("OUTLOOK")) { p.Kill(); }
            }
    
            public static void SendMail(string Receiver, string Subject, string Body)
            {
                bool StillRunning = false;
                OL.Application OlApp = GetOutlook(out StillRunning);
                OL.NameSpace NS = OlApp.GetNamespace("MAPI");
                /*Modification here...*/
                OL.MAPIFolder MFold = NS.GetDefaultFolder(OL.OlDefaultFolders.olFolderOutbox);         
                OL.MailItem MI = OlApp.CreateItem(OL.OlItemType.olMailItem);
                MI.To = Receiver;
                MI.Subject = Subject;
                MI.Body = Body;
    
                /*Modification here...*/
                int nOutItems = MFold.Items.Count;            
                MI.Send();
    
                /*Modification here...*/
                while(nOutItems != MFold.Items.Count){System.Threading.Thread.Sleep(250);}
    
                if (!StillRunning)
                {
                    OlApp.Application.Quit();
                    OlApp.Quit();
                    KillOutlook();
                }
            }
        }
    


  • Hinweis: In der Funktion SendMail wird StillRunning als lokale Boolean Variable erzeugt und mit false deklariert. Diese ändert sich auch nicht im Verlaufe der Funktion. Und sie wird die klasseneigene, gleichnamige Variable in dem Kontext auch überschreiben, weil lokale Variablen, soweit ich weiß, stets zuerst abgegriffen werden.

    Wenn du die klasseneigene Variable zu Beginn abändern willst, nimm einfach das bool weg.