Pregunta

Necesito la capacidad de monitorear y leer correos electrónicos de un buzón particular en un servidor MS Exchange (interno de mi empresa). También necesito poder leer la dirección de correo electrónico del remitente, el asunto, el cuerpo del mensaje y descargar un archivo adjunto, si corresponde.

¿Cuál es la mejor manera de hacer esto usando C # (o Vb.net)?

¿Fue útil?

Solución

Es un desastre. MAPI o CDO a través de una DLL de interoperabilidad .NET es oficialmente no compatible con Microsoft - parecerá funcionar bien, pero hay problemas con las pérdidas de memoria debido a su memoria diferente modelos. Puede usar CDOEX, pero eso solo funciona en el servidor de Exchange en sí, no de forma remota; inútil. Podría interoperar con Outlook, pero ahora acaba de depender de Outlook; exageración Finalmente, puede usar soporte WebDAV de Exchange 2003 , pero WebDAV es complicado, .NET tiene un soporte integrado deficiente para él, y (para agregar insulto a la lesión) Exchange 2007 deja casi por completo el soporte WebDAV.

¿Qué debe hacer un chico? Terminé usando componente IMAP de AfterLogic para comunicarme con mi servidor Exchange 2003 a través de IMAP, y esto terminó funcionando muy bien. (Normalmente busco bibliotecas gratuitas o de código abierto, pero encontré que todas las .NET querían, especialmente cuando se trata de algunas de las peculiaridades de la implementación IMAP de 2003, y esta fue lo suficientemente barata y funcionó en la primera intente. Sé que hay otros por ahí.)

Si su organización está en Exchange 2007, sin embargo, tiene suerte. Exchange 2007 viene con una interfaz de servicio web basada en SOAP que finalmente proporciona un forma unificada e independiente del idioma de interactuar con el servidor de Exchange. Si puede hacer que 2007+ sea un requisito, este es definitivamente el camino a seguir. (Lamentablemente para mí, mi compañía tiene una política de "pero 2003 no está rota").

Si necesita conectar Exchange 2003 y 2007, IMAP o POP3 es definitivamente el camino a seguir.

Otros consejos

Um,

Puede que sea un poco tarde aquí, pero ¿no es este el punto para EWS?

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

Toma alrededor de 6 líneas de código para obtener el correo de un buzón:

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. La API preferida actualmente (Exchange 2013 y 2016) es EWS . Está puramente basado en HTTP y se puede acceder desde cualquier idioma, pero hay . Net y Java bibliotecas específicas.

    Puede usar EWSEditor para jugar con la API.

  2. MAPI extendido . Esta es la API nativa utilizada por Outlook. Termina usando el proveedor MSEMS Exchange MAPI, que puede comunicarse con Exchange usando RPC (Exchange 2013 ya no lo admite) o RPC-over-HTTP (Exchange 2007 o más reciente) o MAPI-over-HTTP (Intercambio 2013 y más reciente).

    Solo se puede acceder a la API en sí desde C ++ no administrado o Delphi . También puede usar Redemption (cualquier idioma) - es RDO es un contenedor de MAPI extendido. Para usar MAPI extendido, debe instalar Outlook o independiente ( Exchange) versión de MAPI (en soporte extendido, y no soporta archivos Unicode PST y MSG y no puede acceder a Exchange 2016). MAPI extendido se puede utilizar en un servicio.

    Puedes jugar con la API usando OutlookSpy o MFCMAPI .

  3. Modelo de objetos de Outlook : no es específico de Exchange, pero permite el acceso a todos los datos disponibles en Outlook en la máquina donde se ejecuta el código. No se puede usar en un servicio.

  4. Exchange Active Sync . Microsoft ya no invierte recursos significativos en este protocolo.

  5. Outlook solía instalar la biblioteca CDO 1.21 (envuelve MAPI extendido), pero Microsoft había dejado de usarlo y ya no recibe ninguna actualización.

  6. Solía ??haber un contenedor .Net MAPI de terceros llamado MAPI33, pero ya no se está desarrollando o admitiendo.

  7. WebDAV - obsoleto.

  8. Objetos de datos de colaboración para Exchange (CDOEX) - en desuso.

  9. Proveedor OLE DB de Exchange (EXOLEDB) - obsoleto.

Aquí hay un código antiguo que tenía para hacer WebDAV. Creo que fue escrito contra Exchange 2003, pero ya no recuerdo nada. Siéntase libre de pedirlo prestado si es útil ...

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

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

Utilicé código que fue publicado en CodeProject.com . Si desea utilizar POP3, es una de las mejores soluciones que he encontrado.

Si su servidor de Exchange está configurado para admitir POP o IMAP, esa es una salida fácil.

Otra opción es el acceso a WebDAV. hay una biblioteca disponible para eso. Esta podría ser su mejor opción.

Creo que hay opciones que usan objetos COM para acceder a Exchange, pero no estoy seguro de lo fácil que es.

Todo depende de lo que su administrador esté dispuesto a darle acceso, supongo.

Debería poder usar MAPI para acceder al buzón y obtener la información que necesita. Desafortunadamente, la única biblioteca .NET MAPI (MAPI33) que conozco parece estar sin mantenimiento. Esta solía ser una excelente manera de acceder a MAPI a través de .NET, pero ahora no puedo hablar de su efectividad. Hay más información sobre dónde puede obtenerla aquí: ¿Ubicación de descarga para MAPI33.dll?

Obtuve una solución al final usando Redemption, eche un vistazo a estas preguntas ...

Una opción es usar Outlook. Tenemos una aplicación de administrador de correo que accede a un servidor de intercambio y utiliza Outlook como interfaz. Está sucio pero funciona.

Código de ejemplo:

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);
        }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top