首页 文章

在C#中阅读MS Exchange电子邮件

提问于
浏览
85

我需要能够监视和读取来自MS Exchange Server(我公司内部)上的特定邮箱的电子邮件 . 我还需要能够阅读发件人的电子邮件地址,主题,邮件正文并下载附件(如果有的话) .

使用C#(或Vb.net)执行此操作的最佳方法是什么?

9 回答

  • 0

    一团糟 . 通过.NET互操作DLL的MAPI或CDO是officially unsupported by Microsoft - 它似乎工作正常,但由于它们的内存模型不同,存在内存泄漏问题 . 您可以使用CDOEX,但这只适用于Exchange服务器本身,而不是远程;无用 . 你可以与Outlook互操作,但现在你只是依赖于Outlook;矫枉过正 . 最后,您可以使用Exchange 2003's WebDAV support,但WebDAV很复杂,.NET内置支持很差,并且(为了加重损害)Exchange 2007几乎完全放弃了WebDAV支持 .

    什么人要做?我最终使用AfterLogic's IMAP component通过IMAP与我的Exchange 2003服务器进行通信,结果运行得很好 . (我通常会寻找免费或开源的库,但我发现所有的.NET都需要 - 特别是当涉及到2003年IMAP实现的一些怪癖时 - 这个很便宜且在第一个工作试试 . 我知道那里还有其他人 . )

    但是,如果您的组织在Exchange 2007上,那么您很幸运 . Exchange 2007 comes with a SOAP-based Web service interface最终提供了一种与Exchange服务器交互的统一,与语言无关的方式 . 如果你能满足2007的要求,这绝对是一条必经之路 . (可悲的是,我的公司有一个_815784政策 . )

    如果您需要桥接Exchange 2003和2007,那么IMAP或POP3绝对是您的选择 .

  • 0

    嗯,

    我可能在这里有点太晚了,但这不是EWS的重点吗?

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

    需要大约6行代码才能从邮箱中获取邮件:

    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 );
    }
    
  • 0
    • 当前首选(Exchange 2013和2016)API是EWS . 它纯粹基于HTTP,可以从任何语言访问,但有.NetJava特定的库 .

    您可以使用EWSEditor来使用API .

    • Extended MAPI . 这是Outlook使用的本机API . 它最终使用 MSEMS Exchange MAPI提供程序,该提供程序可以使用RPC(Exchange 2013不再支持它)或RPC-over-HTTP(Exchange 2007或更高版本)或MAPI-over-HTTP(Exchange 2013和更高版本)与Exchange通信 .

    API本身只能从非托管C或Delphi访问 . 您还可以使用Redemption(任何语言) - 其RDO对象系列是扩展MAPI包装器 . 若要使用扩展MAPI,您需要安装Outlook或standalone (Exchange) version of MAPI(在扩展支持上,它不支持Unicode PST和MSG文件,并且无法访问Exchange 2016) . 扩展MAPI可用于服务 .

    您可以使用OutlookSpyMFCMAPI来使用API .

    • Outlook Object Model - 不是特定于Exchange的,但它允许访问运行代码的计算机上的Outlook中可用的所有数据 . 不能用于服务 .

    • Exchange Active Sync . Microsoft不再向此协议投入任何重要资源 .

    • Outlook用于安装CDO 1.21库(它包装了扩展MAPI),但它已被Microsoft弃用,不再接收任何更新 .

    • 曾经有一个名为MAPI33的第三方.Net MAPI包装器,但它不再被开发或支持 .

    • WebDAV - 已弃用 .

    • Exchange协作数据对象(CDOEX) - 已弃用 .

    • Exchange OLE DB提供程序(EXOLEDB) - 已弃用 .

  • 10

    这里有一些我用来做WebDAV的旧代码 . 我认为它是针对Exchange 2003编写的,但我不记得了 . 如果它有用,请随意借用它...

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

    和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; }
        }
    }
    
  • 0

    我使用了published on CodeProject.com的代码 . 如果你想使用POP3,它是我找到的更好的解决方案之一 .

  • 57

    如果您的Exchange服务器配置为支持POP或IMAP,那么这是一个简单的方法 .

    另一种选择是WebDAV访问 . 有一个library可用 . 这可能是您最好的选择 .

    我认为有使用COM对象访问Exchange的选项,但我不确定它是多么容易 .

    这完全取决于您的管理员愿意为您提供的访问权限 .

  • 87

    您应该能够使用MAPI访问邮箱并获取所需的信息 . 不幸的是,我所知道的唯一.NET MAPI库(MAPI33)似乎没有维护 . 这曾经是通过.NET访问MAPI的好方法,但是我可以在这里获得更多关于你可以在哪里获得它的信息:Download location for MAPI33.dll?

  • 16

    我使用Redemption最终得到了一个解决方案,看看这些问题......

  • 1

    一种选择是使用Outlook . 我们有一个邮件管理器应用程序访问Exchange服务器并使用outlook作为接口 . 它脏,但它的工作原理 .

    示例代码:

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

相关问题