none
Silent Mails versenden

    Frage

  • Hallo zusammen

    Ich suche derzeit nach einer Lösung, um mit meinem VB.NET Programm eMails zu versenden. Dies sollte bis auf eine Bestätigung, dass die Mail versendet wurde (ob es angekommen ist, kann man natürlich dabei nicht überprüfen...) silent, also ohne Dialoge geschehen (der Inhalt, Empfänger etc., bestimmt das Programm).

    Die versendete Mail sollte danach im "gesendete Nachrichten" Ordner des angemeldeten Benutzers erscheinen (Outlookprofil oder ähnlich wird vorausgesetzt)

    Nun gibt es dabei wohl 2 Varianten:
    - MAPI
    - direkt via SMTP

    Meine Fragen vor allem zu MAPI:
    - ist MAPI noch aktuell?
    - wie überprüfe ich nach mail.send() ob die Mail wirklich rausgegangen ist?

    Oder gibt es noch eine dritte, bessere Variante?

    Vielen Dank für alle Hinweise!

    Jonas
    Mittwoch, 17. Juni 2009 08:13

Antworten

  • Hallo Jonas,
    Prinzipiell sind alle drei Möglichkeiten gegeben, abhängig davon welche Infrastruktur gegeben ist und welchen Weg Du gehen möchtest.

    1. MAPI

    Das Versenden über MAPI ist prinzipiell möglich. Allerdings musst Du dafür mittels P/Invoke auf die Funktionen MAPILogon und MAPISendMail aus MAPI32.DLL zurückgreifen. Infos dazu findest du unter [1]. Da es hier keine .NET Klassen gibt, musst du aber sämtliche Funktionalität zunächst selbst schreiben. Um das halbwegs ordentlich zu machen dürfte der Aufwand bei ca. 500-800 LOC liegen. Nachteil hier: Dein Default-MAPI Client wird beim senden der Mail anspringen, das dürfte in aller Regel Outlook Express sein. Das „heimliche“ Senden dürfte darüber hinaus nicht funktionieren, d.h. der Benutzer wird immer das Nachrichtenfenster sehen.

    2. SMTP

    SMTP  geht relativ einfach unter Zuhilfenahme von System.Net.Mail [2]:

    using System.Net.Mail;
    ...
    MailMessage mail = new MailMessage();
    
    mail.From = new MailAddress("john.smith@example.org");
    mail.To.Add("jane.smith@example.org");
    
    mail.Subject = "Geheime Nachricht";
    mail.Body = "Dies ist eine gehemine Nachticht.";
    
    SmtpClient smtp = new SmtpClient("127.0.0.1");
    smtp.Send(mail);
    Der Benutzer wird hiervon überhaupt nichts mitbekommen. Nachteil hier ist, dass Du direkten Zugriff auf einen SMTP Server benötigst, dich ggf. authentifizieren musst und dass Deine Nachricht nicht in Outlook landet, da sie direkt über SMTP versendet wird.

    3. Outlook SMTP u.Exchange

    Der programmatische Zugriff auf Outlook ist mittels der 2007 Microsoft Office System Update: Redistributable Primary Interop Assemblies [3] möglich (Office 11 und Office 12).

    using Outlook = Microsoft.Office.Interop.Outlook;
    ...
    Outlook.Application app = new Outlook.Application();
    Outlook.MailItem mail = (Outlook.MailItem) app.CreateItem(Outlook.OlItemType.olMailItem);
    
    mail.To = "jane.smith@example.org";
    
    mail.Subject = "Geheime Nachricht";
    mail.Body = "Dies ist eine gehemine Nachticht.";
    
    mail.Send();
    

    Das dürfte am ehesten dem entsprechen, was Du suchst. Der Benutzer wird die Nachricht nicht sehen,  aber sie wird im Outlook Postausgang landen und in aller Regel nach dem Senden im Ordner „Gesendete Nachrichten“ liegen. Outlook ist dabei egal, ob der Benutzer ein SMTP Postfach oder Exchange verwendet.  Etwas mehr Aufwand ist nötigt wenn mehre Profile vorliegen, bzw. wenn keine Outlook Instanz gestartet ist, musst Du zunächst  COMExceptions behandeln und abwarten bis OL gestartet ist.

    [1] http://www.pinvoke.net/
    [2] http://www.systemnetmail.com/faq/3.1.1.aspx
    [3] http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=59daebaa-bed4-4282-a28c-b864d8bfa513

    Freitag, 19. Juni 2009 18:21

Alle Antworten

  • Ich nehme an (weil ich es noch nie gemacht habe) daß sich Outlook auch via Automation steuern lassen sollte. Das wäre Variante drei. Variante vier (die ich schon gemacht habe) ist via Exchange Web Services die Email direkt zu verliefern - setzt allerdings voraus daß Outlook + Exchange und nicht Outlook + beliebiger Mailserver verwendet wird.

    Chris

    Christoph Wille - MVP ASP.NET, Glengamoi Alumni - Realnamen sind ein Gebot der Höflichkeit in der Community
    Mittwoch, 17. Juni 2009 13:56
  • Hallo Jonas,
    Prinzipiell sind alle drei Möglichkeiten gegeben, abhängig davon welche Infrastruktur gegeben ist und welchen Weg Du gehen möchtest.

    1. MAPI

    Das Versenden über MAPI ist prinzipiell möglich. Allerdings musst Du dafür mittels P/Invoke auf die Funktionen MAPILogon und MAPISendMail aus MAPI32.DLL zurückgreifen. Infos dazu findest du unter [1]. Da es hier keine .NET Klassen gibt, musst du aber sämtliche Funktionalität zunächst selbst schreiben. Um das halbwegs ordentlich zu machen dürfte der Aufwand bei ca. 500-800 LOC liegen. Nachteil hier: Dein Default-MAPI Client wird beim senden der Mail anspringen, das dürfte in aller Regel Outlook Express sein. Das „heimliche“ Senden dürfte darüber hinaus nicht funktionieren, d.h. der Benutzer wird immer das Nachrichtenfenster sehen.

    2. SMTP

    SMTP  geht relativ einfach unter Zuhilfenahme von System.Net.Mail [2]:

    using System.Net.Mail;
    ...
    MailMessage mail = new MailMessage();
    
    mail.From = new MailAddress("john.smith@example.org");
    mail.To.Add("jane.smith@example.org");
    
    mail.Subject = "Geheime Nachricht";
    mail.Body = "Dies ist eine gehemine Nachticht.";
    
    SmtpClient smtp = new SmtpClient("127.0.0.1");
    smtp.Send(mail);
    Der Benutzer wird hiervon überhaupt nichts mitbekommen. Nachteil hier ist, dass Du direkten Zugriff auf einen SMTP Server benötigst, dich ggf. authentifizieren musst und dass Deine Nachricht nicht in Outlook landet, da sie direkt über SMTP versendet wird.

    3. Outlook SMTP u.Exchange

    Der programmatische Zugriff auf Outlook ist mittels der 2007 Microsoft Office System Update: Redistributable Primary Interop Assemblies [3] möglich (Office 11 und Office 12).

    using Outlook = Microsoft.Office.Interop.Outlook;
    ...
    Outlook.Application app = new Outlook.Application();
    Outlook.MailItem mail = (Outlook.MailItem) app.CreateItem(Outlook.OlItemType.olMailItem);
    
    mail.To = "jane.smith@example.org";
    
    mail.Subject = "Geheime Nachricht";
    mail.Body = "Dies ist eine gehemine Nachticht.";
    
    mail.Send();
    

    Das dürfte am ehesten dem entsprechen, was Du suchst. Der Benutzer wird die Nachricht nicht sehen,  aber sie wird im Outlook Postausgang landen und in aller Regel nach dem Senden im Ordner „Gesendete Nachrichten“ liegen. Outlook ist dabei egal, ob der Benutzer ein SMTP Postfach oder Exchange verwendet.  Etwas mehr Aufwand ist nötigt wenn mehre Profile vorliegen, bzw. wenn keine Outlook Instanz gestartet ist, musst Du zunächst  COMExceptions behandeln und abwarten bis OL gestartet ist.

    [1] http://www.pinvoke.net/
    [2] http://www.systemnetmail.com/faq/3.1.1.aspx
    [3] http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=59daebaa-bed4-4282-a28c-b864d8bfa513

    Freitag, 19. Juni 2009 18:21
  • Hi Andreas
    Vielen Dank für die kompetente Auflistung! Tatsächlich scheint Variante 3 am meisten das zu sein, was ich suche. Dazu noch 2 Fragen:

    1. Funktioniert diese Technik nur mit Office Outlook und nicht mit Outlook Express? Und welche Outlook Version ist dazu mindestens notwendig?

    2. Wie kann ich überprüfen, ob die Mail wirklich rausgegangen ist? Muss ich dazu manuel den "Sent Mail" Ordner überwachen? Oder gibt es da irgend ein Event oder ähnliches?



    Vielen Dank nochmal!

    Gruss Jonas
    Montag, 22. Juni 2009 06:58
  • Hi Jonas,

    die oben referenzierte Office PIA soll anglich für  Office 2003 und Office 2007 funktionieren. Selbst habe ich Office 2003 damit noch nicht anprogrammiert aber die entsprechenden Namespaces gesehen. Zur ganzen Outlook-Programmier-Thematik gibt es auch das Buch "Programming Applications for Office outlook 2007" [1] - soweit ich weiss allerdings auf Englisch.

    Outlook Express geht meines Wissens nicht so einfach. Siehe hierzu auch die beiden Artikel unter [1] und [2]. Es scheint allerdings einen komerziellen Outlook Express Wrapper/Vista Mail zu geben [3]. Über Qualität oder Funktionsumfang kann ich leider keine Aussage treffen.

    Bezüglich 2., da gibt es jede Menge Events die über die Outlook PIA zugänglich sind. Für Deinen Fall sollte wohl der ApplicationEvents_10_ItemSendEventHandler das Richtige sein. Eine Übersicht über den Microsoft.Office.Interop.Outlook Namespace findest Du unter [4]. Ein ganz guten  Ausgangspunkt in der dt. MSDN ist [5]. Da findest Du auch Links zu dedizierten Beispielen welche das Outlook Modell verwenden.


    [1] http://support.microsoft.com/kb/239576
    [2] http://support.microsoft.com/kb/216281 
    [3] http://www.add-in-express.com/programming-outlook-express/ 
    [4] http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.aspx
    [5] http://msdn.microsoft.com/de-de/library/ms268893(VS.80).aspx
    Dienstag, 23. Juni 2009 16:48
  • Hallo,
    diese Darstellung war für mich sehr hilfreich.
    Manfred Keuter
    Mittwoch, 12. August 2009 21:46