wake-up-neo.net

Lesen Sie MS Exchange-E-Mails in C #

Ich muss in der Lage sein, E-Mails von einem bestimmten Postfach auf einem MS Exchange Server (firmenintern) zu überwachen und zu lesen. Ich muss auch in der Lage sein, die E-Mail-Adresse, den Betreff und den Nachrichtentext des Absenders zu lesen und gegebenenfalls einen Anhang herunterzuladen.

Was ist der beste Weg, um dies mit C # (oder Vb.net) zu tun?

88
vajarov

Es ist ein Chaos. MAPI oder CDO über ein .NET-Interop DLL ist offiziell von Microsoft nicht unterstützt - es scheint gut zu funktionieren, aber es gibt Probleme mit Speicherlecks aufgrund ihrer unterschiedlichen Sie könnten CDOEX verwenden, aber das funktioniert nur auf dem Exchange-Server selbst, nicht remote. Sie könnten mit Outlook interagieren, aber jetzt haben Sie gerade eine Abhängigkeit von Outlook hergestellt. WebDAV-Unterstützung für Exchange 20 , aber WebDAV ist kompliziert, .NET bietet eine unzureichende integrierte Unterstützung, und (um die Verletzung noch schlimmer zu machen) Exchange 2007 wird fast vollständig gelöscht WebDAV-Unterstützung.

Was kann ein Mann tun? Am Ende habe ich AfterLogics IMAP-Komponente verwendet, um über IMAP mit meinem Exchange 2003-Server zu kommunizieren, und dies hat sehr gut funktioniert. (Normalerweise suche ich nach freien oder Open-Source-Bibliotheken, aber ich fand alle .NET-Bibliotheken mangelhaft - besonders wenn es um einige der Macken der IMAP-Implementierung von 2003 geht - und diese war billig genug und arbeitete an der ersten versuchen Sie es. Ich weiß, es gibt andere da draußen.)

Wenn sich Ihre Organisation jedoch in Exchange 2007 befindet, haben Sie Glück. Exchange 2007 wird mit einer SOAP-basierten Webdienstschnittstelle geliefert , die schließlich eine einheitliche, sprachunabhängige Möglichkeit für die Interaktion mit dem Exchange-Server bietet. Wenn Sie 2007+ zu einer Anforderung machen können, ist dies definitiv der richtige Weg. (Leider hat meine Firma eine "aber 2003 ist nicht gebrochen" -Richtlinie.)

Wenn Sie sowohl Exchange 2003 als auch 2007 überbrücken müssen, ist IMAP oder POP3 definitiv der richtige Weg.

89

Äh,

Ich bin vielleicht ein bisschen zu spät hier, aber ist das nicht der Sinn von EWS?

https://msdn.Microsoft.com/en-us/library/dd633710 (EXCHG.80) .aspx

Benötigt ungefähr 6 Codezeilen, um die Mail aus einer Mailbox zu bekommen:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

//service.Credentials = new NetworkCredential( "{Active Directory ID}", "{Password}", "{Domain Name}" );

service.AutodiscoverUrl( "[email protected]" );

FindItemsResults<Item> findResults = service.FindItems(
   WellKnownFolderName.Inbox,
   new ItemView( 10 ) 
);

foreach ( Item item in findResults.Items )
{
   Console.WriteLine( item.Subject );
}
64
War
  1. Die derzeit bevorzugte API (Exchange 2013 und 2016) ist EWS . Es ist rein HTTP-basiert und kann von jeder Sprache aus aufgerufen werden, es gibt jedoch . Net und Java spezifische Bibliotheken.

    Sie können EWSEditor verwenden, um mit der API zu spielen.

  2. Extended MAPI . Dies ist die native API, die von Outlook verwendet wird. Es wird der Exchange-MAPI-Anbieter MSEMS verwendet, der über RPC (wird von Exchange 2013 nicht mehr unterstützt) oder RPC-over-HTTP (Exchange 2007 oder neuer) oder MAPI-over-HTTP (Exchange) mit Exchange kommunizieren kann 2013 und neuer).

    Auf die API selbst kann nur von nicht verwaltetem C++ oder Delphi zugegriffen werden. Sie können auch Einlösung (jede Sprache) verwenden. Die Objektfamilie RDO ist ein Extended MAPI-Wrapper. Um Extended MAPI verwenden zu können, müssen Sie entweder Outlook oder die eigenständige (Exchange) Version von MAPI (bei erweiterter Unterstützung) installieren. Unicode PST und MSG Dateien und können nicht auf Exchange 2016 zugreifen.) Extended MAPI kann in einem Dienst verwendet werden.

    Sie können mit der API mit OutlookSpy oder MFCMAPI spielen.

  3. Outlook Object Model - Nicht Exchange-spezifisch, ermöglicht jedoch den Zugriff auf alle in Outlook verfügbaren Daten auf dem Computer, auf dem der Code ausgeführt wird. Kann nicht in einem Dienst verwendet werden.

  4. Exchange Active Sync . Microsoft investiert keine wesentlichen Ressourcen mehr in dieses Protokoll.

  5. Outlook wurde zur Installation der CDO 1.21-Bibliothek verwendet (sie umschließt Extended MAPI), wurde jedoch von Microsoft als veraltet eingestuft und erhält keine Updates mehr.

  6. Früher gab es einen .Net MAPI-Wrapper von Drittanbietern namens MAPI33, der jedoch nicht mehr entwickelt oder unterstützt wird.

  7. WebDAV - veraltet.

  8. Collaborative Data Objects for Exchange (CDOEX) - veraltet.

  9. Exchange OLE DB Provider (EXOLEDB) - veraltet.

17

Hier ist ein alter Code, den ich für WebDAV verwendet habe. Ich denke, es wurde gegen Exchange 2003 geschrieben, aber ich erinnere mich nicht mehr. Fühlen Sie sich frei, es zu leihen, wenn es hilfreich ist ...

class MailUtil
{
    private CredentialCache creds = new CredentialCache();

    public MailUtil()
    {
        // set up webdav connection to exchange
        this.creds = new CredentialCache();
        this.creds.Add(new Uri("http://mail.domain.com/Exchange/[email protected]/Inbox/"), "Basic", new NetworkCredential("myUserName", "myPassword", "WINDOWSDOMAIN"));
    }

    /// <summary>
    /// Gets all unread emails in a user's Inbox
    /// </summary>
    /// <returns>A list of unread mail messages</returns>
    public List<model.Mail> GetUnreadMail()
    {
        List<model.Mail> unreadMail = new List<model.Mail>();

        string reqStr =
            @"<?xml version=""1.0""?>
                <g:searchrequest xmlns:g=""DAV:"">
                    <g:sql>
                        SELECT
                            ""urn:schemas:mailheader:from"", ""urn:schemas:httpmail:textdescription""
                        FROM
                            ""http://mail.domain.com/Exchange/[email protected]/Inbox/"" 
                        WHERE 
                            ""urn:schemas:httpmail:read"" = FALSE 
                            AND ""urn:schemas:httpmail:subject"" = 'tbintg' 
                            AND ""DAV:contentclass"" = 'urn:content-classes:message' 
                        </g:sql>
                </g:searchrequest>";

        byte[] reqBytes = Encoding.UTF8.GetBytes(reqStr);

        // set up web request
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://mail.domain.com/Exchange/[email protected]/Inbox/");
        request.Credentials = this.creds;
        request.Method = "SEARCH";
        request.ContentLength = reqBytes.Length;
        request.ContentType = "text/xml";
        request.Timeout = 300000;

        using (Stream requestStream = request.GetRequestStream())
        {
            try
            {
                requestStream.Write(reqBytes, 0, reqBytes.Length);
            }
            catch
            {
            }
            finally
            {
                requestStream.Close();
            }
        }

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            try
            {
                XmlDocument document = new XmlDocument();
                document.Load(responseStream);

                // set up namespaces
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                nsmgr.AddNamespace("a", "DAV:");
                nsmgr.AddNamespace("b", "urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/");
                nsmgr.AddNamespace("c", "xml:");
                nsmgr.AddNamespace("d", "urn:schemas:mailheader:");
                nsmgr.AddNamespace("e", "urn:schemas:httpmail:");

                // Load each response (each mail item) into an object
                XmlNodeList responseNodes = document.GetElementsByTagName("a:response");
                foreach (XmlNode responseNode in responseNodes)
                {
                    // get the <propstat> node that contains valid HTTP responses
                    XmlNode uriNode = responseNode.SelectSingleNode("child::a:href", nsmgr);
                    XmlNode propstatNode = responseNode.SelectSingleNode("descendant::a:propstat[a:status='HTTP/1.1 200 OK']", nsmgr);
                    if (propstatNode != null)
                    {
                        // read properties of this response, and load into a data object
                        XmlNode fromNode = propstatNode.SelectSingleNode("descendant::d:from", nsmgr);
                        XmlNode descNode = propstatNode.SelectSingleNode("descendant::e:textdescription", nsmgr);

                        // make new data object
                        model.Mail mail = new model.Mail();
                        if (uriNode != null)
                            mail.Uri = uriNode.InnerText;
                        if (fromNode != null)
                            mail.From = fromNode.InnerText;
                        if (descNode != null)
                            mail.Body = descNode.InnerText;
                        unreadMail.Add(mail);
                    }
                }

            }
            catch (Exception e)
            {
                string msg = e.Message;
            }
            finally
            {
                responseStream.Close();
            }
        }

        return unreadMail;
    }
}

Und model.Mail:

class Mail
{
    private string uri;
    private string from;
    private string body;

    public string Uri
    {
        get { return this.uri; }
        set { this.uri = value; }
    }

    public string From
    {
        get { return this.from; }
        set { this.from = value; }
    }

    public string Body
    {
        get { return this.body; }
        set { this.body = value; }
    }
}
10
CodingWithSpike

Ich habe Code verwendet, der auf CodeProject.com veröffentlicht wurde . Wenn Sie POP3 verwenden möchten, ist dies eine der besseren Lösungen, die ich gefunden habe.

1
Eldila

Wenn Ihr Exchange-Server für die Unterstützung von POP oder IMAP konfiguriert ist, ist dies ein einfacher Ausweg.

Eine weitere Option ist der WebDAV-Zugriff. Dafür gibt es eine Bibliothek . Dies könnte Ihre beste Option sein.

Ich glaube, es gibt Optionen für den Zugriff auf Exchange mithilfe von COM-Objekten, aber ich bin nicht sicher, wie einfach das ist.

Es hängt alles davon ab, was genau Ihr Administrator bereit ist, Ihnen Zugriff zu gewähren.

0
Denis Troller

Sie sollten MAPI verwenden können, um auf das Postfach zuzugreifen und die benötigten Informationen abzurufen. Leider scheint die einzige mir bekannte .NET MAPI-Bibliothek (MAPI33) nicht gepflegt zu sein. Früher war dies eine großartige Möglichkeit, über .NET auf MAPI zuzugreifen, aber jetzt kann ich nicht über die Effektivität sprechen. Weitere Informationen dazu, wo Sie sie erhalten können, finden Sie hier: Speicherort für MAPI33.dll herunterladen?

0
Chris Hynes

Ich habe eine Lösung gefunden, die letztendlich mit Redemption funktioniert. Schauen Sie sich diese Fragen an ...

0
Paul Rowland

Eine Möglichkeit ist die Verwendung von Outlook. Wir haben eine Mail-Manager-Anwendung, die auf einen Exchange-Server zugreift und Outlook als Schnittstelle verwendet. Es ist schmutzig, aber es funktioniert.

Beispielcode:

public Outlook.MAPIFolder getInbox()
        {
            mailSession = new Outlook.Application();
            mailNamespace = mailSession.GetNamespace("MAPI");
            mailNamespace.Logon(mail_username, mail_password, false, true);
            return MailNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
        }
0
duncane