Pergunta

Preciso da capacidade de monitorar e ler email de uma caixa de correio específica em um servidor MS Exchange (interno para minha empresa). Eu também preciso poder ler o endereço de e -mail, sujeito, disciplina do remetente do remetente e baixar um anexo, se houver.

Qual é a melhor maneira de fazer isso usando c# (ou vb.net)?

Foi útil?

Solução

É uma bagunça. MAPI ou CDO através de uma DLL .NET Interop é Oficialmente não suportado pela Microsoft-Parece funcionar bem, mas há problemas com vazamentos de memória devido aos diferentes modelos de memória. Você pode usar o CDOEX, mas isso só funciona no próprio servidor Exchange, não remotamente; sem utilidade. Você pode integrar o Outlook, mas agora você acabou de depender do Outlook; exagero. Finalmente, você pode usar Suporte Webdav de Exchange 2003, mas Webdav é complicado, o .NET possui um suporte interno ruim para ele e (para adicionar insulto à lesão) Exchange 2007 quase completamente cai Suporte WebDav.

O que um cara deve fazer? Acabei usando Componente IMAP da AfterLogic Para se comunicar com meu servidor Exchange 2003 via IMAP, e isso acabou funcionando muito bem. (Normalmente, procuro bibliotecas gratuitas ou de código aberto, mas encontrei todas as que queriam. tente. Eu sei que existem outros por aí.)

Se sua organização estiver no Exchange 2007, no entanto, você está com sorte. O Exchange 2007 vem com uma interface de serviço da web baseada em sabão Isso finalmente fornece uma maneira unificada e independente de idioma de interagir com o servidor Exchange. Se você pode fazer de 2007+ um requisito, esse é definitivamente o caminho a percorrer. (Infelizmente para mim, minha empresa tem uma política "mas 2003 não está quebrada".)

Se você precisar preencher o Exchange 2003 e 2007, o IMAP ou o POP3 é definitivamente o caminho a percorrer.

Outras dicas

Hum,

Eu posso estar um pouco tarde demais aqui, mas esse não é o ponto de EWS?

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

Leva cerca de 6 linhas de código para obter o correio de uma caixa de correio:

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. A API atualmente preferida (Exchange 2013 e 2016) é EWS. É puramente baseado em http e pode ser acessado a partir de qualquer idioma, mas existem .Internet e Java bibliotecas específicas.

    Você pode usar Ewseditor Para brincar com a API.

  2. Mapi estendido. Esta é a API nativa usada pelo Outlook. Acaba usando o MSEMS O Provedor de MAPI do Exchange, que pode conversar com o Exchange usando o RPC (Exchange 2013, não suporta mais) ou RPC-Over-HTTP (Exchange 2007 ou mais recente) ou Mapi-Over-HTTP (Exchange 2013 e New).

    A API em si só pode ser acessada a partir de C ++ não gerenciado ou Delphi. Você também pode usar Redenção (qualquer idioma) - seu Rdo Família de objetos é um invólucro MAPI estendido. Para usar o MAPI estendido, você precisa instalar o Outlook ou o Versão independente (troca) de mapi (em suporte estendido e não suporta arquivos Unicode PST e MSG e não pode acessar o Exchange 2016). O MAPI estendido pode ser usado em um serviço.

    Você pode brincar com a API usando Outlookspy ou MFCMAPI.

  3. Modelo de objeto do Outlook - Não troca específico, mas permite o acesso a todos os dados disponíveis no Outlook na máquina onde o código é executado. Não pode ser usado em um serviço.

  4. Trocar sincronização ativa. A Microsoft não investe mais recursos significativos nesse protocolo.

  5. O Outlook usado para instalar a biblioteca do CDO 1.21 (envolve o MAPI estendido), mas foi descontinuado pela Microsoft e não recebe mais atualizações.

  6. Costumava haver um wrapper .NET MAPI de terceiros chamado MAPI33, mas não está mais sendo desenvolvido ou suportado.

  7. Webdav - depreciado.

  8. Objetos de dados colaborativos para Exchange (CDOEX) - depreciados.

  9. Provedor de troca OLE DB (EXOLEDB) - depreciado.

Aqui está algum código antigo que eu tinha deitado para fazer o WebDav. Eu acho que foi escrito contra o Exchange 2003, mas não me lembro mais. Sinta -se à vontade para emprestá -lo se for ú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;
    }
}

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

I used code that was published on CodeProject.com. If you want to use POP3, it is one of the better solutions that I have found.

If your Exchange server is configured to support POP or IMAP, that's an easy way out.

Another option is WebDAV access. there is a library available for that. This might be your best option.

I think there are options using COM objects to access Exchange, but I'm not sure how easy it is.

It all depends on what exactly your administrator is willing to give you access to I guess.

You should be able to use MAPI to access the mailbox and get the information you need. Unfortunately the only .NET MAPI library (MAPI33) I know of seems to be unmaintained. This used to be a great way to access MAPI through .NET, but I can't speak to its effectiveness now. There's more information about where you can get it here: Download location for MAPI33.dll?

I got a solution working in the end using Redemption, have a look at these questions...

One option is to use Outlook. We have a mail manager application that access an exchange server and uses outlook as the interface. Its dirty but it works.

Example 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);
        }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top