MS Exchange Server(社内)の特定のメールボックスからの電子メールを監視して読み取る機能が必要です。また、送信者の電子メールアドレス、件名、メッセージ本文を読み取り、添付ファイルがある場合はダウンロードできる必要があります。
C#(またはVB.NET)を使用してこれを行うための最良の方法は何ですか?
MS Exchange Server(社内)の特定のメールボックスからの電子メールを監視して読み取る機能が必要です。また、送信者の電子メールアドレス、件名、メッセージ本文を読み取り、添付ファイルがある場合はダウンロードできる必要があります。
C#(またはVB.NET)を使用してこれを行うための最良の方法は何ですか?
それは混乱です。.NET 相互運用 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 には SOAP ベースの Web サービス インターフェイスが付属しており、言語に依存しない統一された Exchange サーバーとのやり取りの方法が最終的に提供されます。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 またはMAPI のスタンドアロン (Exchange) バージョンのいずれかをインストールする必要があります(拡張サポートで、Unicode PST および MSG ファイルをサポートせず、Exchange 2016 にアクセスできません)。拡張 MAPI は、サービスで使用できます。
OutlookSpyまたはMFCMAPIを使用して API を操作できます。
Outlook オブジェクト モデル- Exchange 固有ではありませんが、コードが実行されているマシン上の Outlook で利用可能なすべてのデータにアクセスできます。サービスでは使用できません。
Exchange アクティブ シンク。Microsoft は、このプロトコルに重要なリソースを投資しなくなりました。
Outlook は CDO 1.21 ライブラリ (Extended MAPI をラップする) をインストールしていましたが、Microsoft によって廃止されたため、更新プログラムを受信しなくなりました。
以前は、MAPI33 と呼ばれるサードパーティの .Net MAPI ラッパーがありましたが、現在は開発またはサポートされていません。
WebDAV - 非推奨。
Collaborative Data Objects for Exchange (CDOEX) - 非推奨。
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 を使用する場合、これは私が見つけた優れたソリューションの 1 つです。
MAPI を使用してメールボックスにアクセスし、必要な情報を取得できるはずです。残念ながら、私が知っている唯一の .NET MAPI ライブラリ (MAPI33) はメンテナンスされていないようです。これは、以前は .NET を介して MAPI にアクセスするための優れた方法でしたが、今ではその有効性について話すことはできません。ここで入手できる場所についての詳細情報があります: MAPI33.dll の場所をダウンロードしますか?
Exchange サーバーが POP または IMAP をサポートするように構成されている場合、それは簡単な方法です。
もう 1 つのオプションは、WebDAV アクセスです。そのために利用できるライブラリがあります。これが最良の選択肢かもしれません。
COM オブジェクトを使用して Exchange にアクセスするオプションがあると思いますが、それがどれほど簡単かはわかりません。
それはすべて、管理者があなたに何へのアクセスを許可しようとしているかにかかっていると思います.
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);
}