Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中阅读MS Exchange电子邮件#_C#_Email_Exchange Server_Mapi - Fatal编程技术网

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

C# 在C中阅读MS Exchange电子邮件#,c#,email,exchange-server,mapi,C#,Email,Exchange Server,Mapi,我需要能够在MS Exchange服务器(公司内部)上监视和读取特定邮箱中的电子邮件。我还需要能够阅读发件人的电子邮件地址、主题、邮件正文,并下载附件(如有) 使用C#(或VB.NET)执行此操作的最佳方法是什么?如果您的Exchange服务器配置为支持POP或IMAP,这是一个简单的解决方法 另一个选项是WebDAV访问。有一个可供选择的方法。这可能是你最好的选择 我认为可以选择使用COM对象访问Exchange,但我不确定这有多容易 我想这完全取决于管理员到底愿意让您访问什么。您应该能够使用

我需要能够在MS Exchange服务器(公司内部)上监视和读取特定邮箱中的电子邮件。我还需要能够阅读发件人的电子邮件地址、主题、邮件正文,并下载附件(如有)


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

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

另一个选项是WebDAV访问。有一个可供选择的方法。这可能是你最好的选择

我认为可以选择使用COM对象访问Exchange,但我不确定这有多容易


我想这完全取决于管理员到底愿意让您访问什么。

您应该能够使用MAPI访问邮箱并获取所需信息。不幸的是,据我所知,唯一的.NET MAPI库(MAPI33)似乎没有维护。这曾经是通过.NET访问MAPI的一种很好的方式,但我现在不能说它的有效性。这里有更多关于在哪里可以获得它的信息:

我使用了以前的代码。如果您想使用POP3,这是我找到的一个更好的解决方案。

这真是一团糟。通过.NET互操作DLL的MAPI或CDO是--它似乎可以正常工作,但由于内存模型不同,内存泄漏会出现问题。您可以使用CDOEX,但这只能在Exchange服务器上工作,不能远程工作;没用。您可以与Outlook进行互操作,但现在您只依赖Outlook;太过分了。最后,您可以使用,但WebDAV很复杂,.NET对它的内置支持很差,而且(雪上加霜的是)Exchange2007几乎完全放弃了WebDAV支持

男人该怎么办?最后,我使用通过IMAP与Exchange2003服务器通信,结果非常好。(我通常会寻找免费的或开源的库,但我发现所有的.NET库都是需要的——特别是当涉及到2003年IMAP实现的一些怪癖时——而这一个非常便宜,而且在第一次尝试时就成功了。我知道还有其他的。)

但是,如果您的组织在Exchange2007上,那么您就很幸运了。这最终提供了一种与Exchange服务器交互的统一、独立于语言的方式。如果你能让2007+成为一个要求,这绝对是一条路要走。(遗憾的是,我的公司有一个“但2003年没有破产”的政策。)


如果您需要同时连接Exchange 2003和2007,IMAP或POP3绝对是一个不错的选择。

我最终找到了一个使用Redemption的解决方案,请看一下这些问题


以下是一些我用来编写WebDAV的旧代码。我想它是针对Exchange2003写的,但我已经不记得了。如果有用的话,可以随意借用

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

一种选择是使用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);
        }

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

从邮箱获取邮件需要大约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 );
}
ExchangeService服务=新的ExchangeService(ExchangeVersion.Exchange2007\u SP1);
//service.Credentials=newnetworkcredential(“{activedirectory ID}”,“{Password}”,“{Domain Name}”);
service.AutodiscoverUrl(“第一个。Last@MyCompany.com" );
FindItemsResults findResults=service.FindItems(
WellKnownFolderName.Inbox,
新项目视图(10)
);
foreach(findResults.Items中的项目)
{
Console.WriteLine(项目主题);
}
  • 目前首选的API(Exchange 2013和2016)为。它完全基于HTTP,可以从任何语言访问,但也有一些特定的库

    您可以使用来使用API

  • 。这是Outlook使用的本机API。它最终使用
    MSEMS
    Exchange MAPI提供程序,该提供程序可以使用RPC(Exchange 2013不再支持它)或通过HTTP的RPC(Exchange 2007或更新版本)或通过HTTP的MAPI(Exchange 2013或更新版本)与Exchange进行通信

    API本身只能从非托管C++或。您还可以使用(任何语言)-它的对象族是扩展MAPI包装器。要使用扩展MAPI,您需要安装Outlook或(在扩展支持上,它不支持Unicode PST和MSG文件,并且无法访问Exchange 2016)。扩展MAPI可以在服务中使用

    您可以使用或来使用API

  • -不是特定于Exchange的,但它允许在运行代码的计算机上访问Outlook中的所有可用数据。无法在服务中使用

  • 。Microsoft不再为此协议投入任何重要资源

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

  • 以前有一个名为MAPI33的第三方.Net MAPI包装器,但现在已不再开发或支持它

  • WebDAV-已弃用

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

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


  • 基于SOAP的web服务由Microsoft包装以简化访问-现在建议使用Exchange web服务管理的API 1.0 SDK:如果我想在Win2003中使用Windows服务访问Exchange 2003,几乎就好像Microsoft将其设计为除了Outlook之外的任何东西都无法运行一样??我需要在服务器win2003中安装Outlook 2003或2007?此后,Microsoft发布了适用于Exchange 2007 SP1和v2010的Exchange Web Services托管API,允许用户通过编程方式进入邮箱,而无需使用Outlook。我的博客上有两篇文章讨论了这种方法:-Exchange Web Services Managed API 1.0 SDK是Microsoft推荐的更新Exchange prog的方法
    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 );
    }