Question

J'ai besoin de pouvoir surveiller et lire les courriers électroniques d'une boîte aux lettres particulière sur un serveur MS Exchange (interne à ma société). Je dois également pouvoir lire l'adresse électronique de l'expéditeur, son objet et le corps du message, ainsi que télécharger une pièce jointe, le cas échéant.

Quel est le meilleur moyen de faire cela en utilisant C # (ou Vb.net)?

Était-ce utile?

La solution

C'est un gâchis. MAPI ou CDO via une DLL d'interopérabilité .NET est officiellement non pris en charge par Microsoft - il semblera bien fonctionner, mais la mémoire présente des problèmes de fuites de mémoire. des modèles. Vous pouvez utiliser CDOEX, mais cela ne fonctionne que sur le serveur Exchange lui-même, pas à distance. inutile. Vous pouvez interagir avec Outlook, mais vous venez maintenant de créer une dépendance sur Outlook. surpuissance. Enfin, vous pouvez utiliser le prise en charge de WebDAV par Exchange 2003 , mais WebDAV est compliqué. La prise en charge intégrée de .NET est faible et (pour ajouter une insulte à la blessure) Exchange 2007 supprime presque complètement la prise en charge de WebDAV .

Qu'est-ce qu'un gars à faire? J'ai fini par utiliser le composant IMAP d'AfterLogic pour communiquer avec mon serveur Exchange 2003 via IMAP, et cela a fini par très bien fonctionner. (Je cherche normalement des bibliothèques libres ou à code source ouvert, mais j’ai trouvé toutes les bibliothèques .NET qui me manquaient - en particulier en ce qui concerne certaines des bizarreries de l’implémentation IMAP de 2003 - et celle-ci était assez bon marché et a fonctionné pour la première fois. essayez, je sais qu’il en existe d’autres.)

Si votre organisation est sur Exchange 2007, vous avez de la chance. Exchange 2007 est livré avec une interface de service Web basée sur SOAP qui fournit enfin une façon unifiée, indépendante de la langue, d’interagir avec le serveur Exchange. Si vous pouvez faire de 2007+ une exigence, c'est vraiment la voie à suivre. (Malheureusement pour moi, mon entreprise applique une politique "mais 2003 n'est pas rompue".)

Si vous devez créer un pont entre Exchange 2003 et 2007, utilisez IMAP ou POP3.

Autres conseils

Euh,

Je pourrais être un peu trop tard ici, mais est-ce que ce n'est pas un peu le but de l'EWS?

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

Prend environ 6 lignes de code pour extraire le courrier d'une boîte aux lettres:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

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

service.AutodiscoverUrl( "First.Last@MyCompany.com" );

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

foreach ( Item item in findResults.Items )
{
   Console.WriteLine( item.Subject );
}
  1. L'API actuellement préférée (Exchange 2013 et 2016) est EWS . Il est purement basé sur HTTP et est accessible à partir de n’importe quelle langue, mais il existe . Net et bibliothèques spécifiques à Java .

    Vous pouvez utiliser EWSEditor pour jouer avec l'API.

  2. MAPI étendu . C'est l'API native utilisée par Outlook. Il finit par utiliser le fournisseur MAPI Exchange MSEMS , qui peut communiquer avec Exchange à l'aide de RPC (Exchange 2013 ne le prend plus en charge) ou RPC sur HTTP (Exchange 2007 ou version ultérieure) ou MAPI sur HTTP. (Exchange 2013 et plus récent).

    L’API elle-même est accessible uniquement à partir de C ++ non géré ou de Delphi . Vous pouvez également utiliser Rachat (toutes les langues) - son RDO La famille d'objets est un wrapper MAPI étendu. Pour utiliser Extended MAPI, vous devez installer Outlook ou le autonome ( Exchange) de la version MAPI (prise en charge étendue, ne prend pas en charge les fichiers Unicode PST et MSG et ne peut pas accéder à Exchange 2016). MAPI étendu peut être utilisé dans un service.

    Vous pouvez jouer avec l'API en utilisant OutlookSpy ou MFCMAPI .

  3. Modèle d'objet Outlook - non spécifique à Exchange, mais il permet d'accéder à toutes les données disponibles dans Outlook sur la machine sur laquelle le code est exécuté. Ne peut pas être utilisé dans un service.

  4. Exchange Active Sync . Microsoft n'investit plus de ressources importantes dans ce protocole.

  5. Outlook utilisait la bibliothèque CDO 1.21 (elle englobe Extended MAPI), mais elle était obsolète par Microsoft et ne recevait plus aucune mise à jour.

  6. Il existait auparavant un wrapper MAPI .Net tiers appelé MAPI33, mais celui-ci n'est plus développé ni pris en charge.

  7. WebDAV - obsolète.

  8. Objets de données collaboratifs pour Exchange (CDOEX) - obsolète.

  9. Fournisseur Exchange OLE DB (EXOLEDB) - obsolète.

Voici un vieux code que j'avais dans les parages pour faire WebDAV. Je pense que cela a été écrit contre Exchange 2003, mais je ne m'en souviens plus. N'hésitez pas à l'emprunter si cela vous aide ...

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/me@domain.com/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/me@domain.com/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/me@domain.com/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;
    }
}

Et 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; }
    }
}

J'ai utilisé du code publié sur CodeProject.com . Si vous souhaitez utiliser POP3, c'est l'une des meilleures solutions que j'ai trouvées.

Si votre serveur Exchange est configuré pour prendre en charge POP ou IMAP, c'est une solution de facilité.

Une autre option est l’accès WebDAV. Une bibliothèque est disponible à cet effet. Cela pourrait être votre meilleure option.

Je pense qu'il existe des options utilisant des objets COM pour accéder à Exchange, mais je ne sais pas à quel point c'est facile.

Tout dépend de ce que votre administrateur est disposé à vous donner exactement, je suppose.

Vous devriez pouvoir utiliser MAPI pour accéder à la boîte aux lettres et obtenir les informations dont vous avez besoin. Malheureusement, la seule bibliothèque .NET MAPI (MAPI33) que je connaisse ne semble pas être maintenue. C'était un excellent moyen d'accéder à MAPI via .NET, mais je ne peux pas parler de son efficacité pour le moment. Vous trouverez plus d'informations sur l'endroit où vous pouvez l'obtenir ici: Emplacement de téléchargement de MAPI33.dll?

J'ai finalement trouvé une solution qui utilise Redemption, jetez un coup d'œil à ces questions ...

Une option consiste à utiliser Outlook. Nous avons une application de gestion de courrier qui accède à un serveur d’échange et utilise Outlook comme interface. C'est sale mais ça marche.

Exemple de code:

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);
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top