MS Exchange Server (회사 내부)의 특정 사서함에서 전자 메일을 모니터링하고 읽을 수있는 기능이 필요합니다. 또한 보낸 사람의 전자 메일 주소, 제목, 메시지 본문을 읽고 첨부 파일 (있는 경우)을 다운로드 할 수 있어야합니다.
C # (또는 VB.NET)을 사용하여이를 수행하는 가장 좋은 방법은 무엇입니까?
답변
엉망입니다. .NET interop DLL을 통한 MAPI 또는 CDO는 공식적으로 Microsoft에서 지원 하지 않습니다. 제대로 작동하는 것처럼 보이지만 메모리 모델이 다르기 때문에 메모리 누수 문제가 있습니다. CDOEX를 사용할 수 있지만 원격이 아닌 Exchange 서버 자체에서만 작동합니다. 쓸모없는. Outlook과 상호 운용 할 수 있지만 이제 Outlook에 대한 종속성을 만들었습니다. 지나침. 마지막으로 Exchange 2003의 WebDAV 지원을 사용할 수 있지만 WebDAV는 복잡하고 .NET은 기본 제공 지원이 부족하며 (부상을 더하기 위해) Exchange 2007 은 WebDAV 지원을 거의 완전히 중단 합니다.
할 사람은 무엇입니까? 결국 AfterLogic의 IMAP 구성 요소 를 사용하여 IMAP 을 통해 Exchange 2003 서버와 통신하게되었고, 결국 매우 잘 작동했습니다. (일반적으로 무료 또는 오픈 소스 라이브러리를 찾아 보지만, 특히 2003 년 IMAP 구현의 일부 단점에 관해서는 .NET 라이브러리가 모두 필요하다는 것을 알았습니다.이 라이브러리는 충분히 저렴하고 첫 번째 다른 사람이 있다는 것을 알고 있습니다.)
그러나 조직이 Exchange 2007을 사용하는 경우 운이 좋습니다. Exchange 2007에는 최종적으로 Exchange 서버와 상호 작용하는 언어 독립적 인 통합 방식을 제공 하는 SOAP 기반 웹 서비스 인터페이스가 함께 제공됩니다 . 2007+를 요구 사항으로 만들 수 있다면 이것이 확실히 갈 길입니다. (나에게 안타깝게도 우리 회사는 “2003 년은 깨지지 않았습니다”라는 정책을 가지고 있습니다.)
Exchange 2003과 2007을 모두 연결해야하는 경우 IMAP 또는 POP3를 사용하는 것이 좋습니다.
답변
음,
나는 여기에 너무 늦었을 수도 있지만 이것이 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 );
}
답변
-
현재 선호되는 (Exchange 2013 및 2016) API는 EWS 입니다. 순전히 HTTP 기반이며 모든 언어에서 액세스 할 수 있지만 .Net 및 Java 특정 라이브러리가 있습니다.
당신이 사용할 수있는 EWSEditor 를 하여 API를 .
-
확장 된 MAPI . Outlook에서 사용하는 기본 API입니다.
MSEMS
RPC (Exchange 2013에서 더 이상 지원하지 않음) 또는 RPC-over-HTTP (Exchange 2007 이상) 또는 MAPI-over-HTTP (Exchange 2013 이상)를 사용하여 Exchange와 통신 할 수 있는 Exchange MAPI 공급자를 사용하게됩니다.API 자체는 관리되지 않는 C ++ 또는 Delphi 에서만 액세스 할 수 있습니다 . Redemption (모든 언어)을 사용할 수도 있습니다. RDO 개체 제품군은 확장 MAPI 래퍼입니다. 확장 MAPI를 사용하려면 Outlook 또는 독립 실행 형 (Exchange) 버전의 MAPI (확장 지원시, 유니 코드 PST 및 MSG 파일을 지원하지 않으며 Exchange 2016에 액세스 할 수 없음)를 설치해야합니다. 서비스에서 확장 MAPI를 사용할 수 있습니다.
OutlookSpy 또는 MFCMAPI를 사용하여 API를 사용할 수 있습니다. .
-
Outlook 개체 모델 -Exchange와 관련이 없지만 코드가 실행되는 컴퓨터의 Outlook에서 사용할 수있는 모든 데이터에 액세스 할 수 있습니다. 서비스에서 사용할 수 없습니다.
-
Exchange Active Sync . Microsoft는 더 이상이 프로토콜에 중요한 리소스를 투자하지 않습니다.
-
Outlook은 CDO 1.21 라이브러리 (확장 MAPI를 포함)를 설치하는 데 사용되었지만 Microsoft에서 더 이상 사용하지 않으며 더 이상 업데이트를받지 않습니다.
-
MAPI33이라는 타사 .Net MAPI 래퍼가 있었지만 더 이상 개발되거나 지원되지 않습니다.
-
WebDAV-더 이상 사용되지 않습니다.
-
CDOEX (Collaborative Data Objects for Exchange)-더 이상 사용되지 않습니다.
-
Exchange OLE DB 공급자 (EXOLEDB)-더 이상 사용되지 않습니다.
답변
다음은 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; }
}
}
답변
CodeProject.com 에 게시 된 코드를 사용했습니다 . POP3를 사용하려면 내가 찾은 더 나은 솔루션 중 하나입니다.
답변
Exchange 서버가 POP 또는 IMAP을 지원하도록 구성되어있는 경우 쉬운 방법입니다.
또 다른 옵션은 WebDAV 액세스입니다. 이를위한 라이브러리가 있습니다. 이것이 최선의 선택 일 수 있습니다.
COM 개체를 사용하여 Exchange에 액세스하는 옵션이 있다고 생각하지만 얼마나 쉬운 지 잘 모르겠습니다.
그것은 모두 관리자가 정확히 무엇에 대한 액세스 권한을 제공 할 것인지에 달려 있습니다.
답변
MAPI를 사용하여 사서함에 액세스하고 필요한 정보를 얻을 수 있어야합니다. 불행히도 내가 아는 유일한 .NET MAPI 라이브러리 (MAPI33)는 유지되지 않는 것 같습니다. 이것은 .NET을 통해 MAPI에 액세스하는 좋은 방법 이었지만 지금은 그 효과에 대해 말할 수 없습니다. 여기에서 얻을 수있는 위치에 대한 자세한 정보가 있습니다. MAPI33.dll의 다운로드 위치?