[C#]Outlookから予定表データとかを取得する

タイトルのようなことをやってみたいと思います。

方法1:OutlookのAPIを使う

Outlookがインストールされている環境であれば、OutlookのAPI越しに予定表データを触れます。以下、サンプルコード。

var app = new Microsoft.Office.Interop.Outlook.Application();
            var ns = app.GetNamespace("MAPI");
            var folder = ns.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
            foreach (AppointmentItem i in folder.Items)
               Console.WriteLine(i.Subject + " start time:" + i.Start);

Microsoft.Office.Interop.Outlookへの参照設定を追加する必要があります。めっちゃ簡単ですね。

方法2:Exchangeサーバに問い合わせる

MS Exchangeを使っているならば、Exchangeサーバに直接問い合わせることも可能です。ExchangeサーバはWeb APIを持っていて、さらに、そのWeb APIをマネージコードから簡単に触るためのExchange Web Services (EWS) Managed API というものがあります。Visual Studioか何かをインストールすると勝手に入るようです。C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.0あたりに入っています。無ければ落としてインストールしてください。ダウンロード先URLは適当に検索してください。(MS関係はすぐにリンク切れになるので)

そしたら、Microsoft.Exchange.WebServices.dllとMicrosoft.Exchange.WebServices.Auth.dllを参照するようにします。(Authのほうは要らないかも)

あとは以下の公式サンプルに倣って書いていくだけ。

Working with the EWS Managed API

コードは以下のような感じ。大部分は上記ページからのコピペ。

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.UseDefaultCredentials = false;
service.Credentials = new WebCredentials("ユーザID", "パスワード");
service.AutodiscoverUrl("メール@アドレス.co.jp", url => true);

// Initialize values for the start and end times, and the number of appointments to retrieve.
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(30);
const int NUM_APPTS = 5;

// Initialize the calendar folder object with only the folder ID. 
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());

// Set the start and end time and number of appointments to retrieve.
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);

// Limit the properties returned to the appointment's subject, start time, and end time.
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);

// Retrieve a collection of appointments by using the calendar view.
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

Console.WriteLine("\nThe first " + NUM_APPTS + " appointments on your calendar from " + startDate.Date.ToShortDateString() +
                  " to " + endDate.Date.ToShortDateString() + " are: \n");

foreach (Appointment a in appointments)
{
    Console.Write("Subject: " + a.Subject.ToString() + " ");
    Console.Write("Start: " + a.Start.ToString() + " ");
    Console.Write("End: " + a.End.ToString());
    Console.WriteLine();
}

メールアドレスからExchangeサーバアドレスを自動検出することができるのだが、これがうまく働かない場合は、以下のように手動設定する。

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.UseDefaultCredentials = false;
service.Credentials = new WebCredentials("ユーザID", "パスワード");
//service.AutodiscoverUrl("メール@アドレス.co.jp", url => true);
service.Url = new Uri("https://サーバー名.co.jp/EWS/Exchange.asmx");

APIのURLは大体上記のような形になる。実際にブラウザからアクセスしてみると、サービスの定義がずらずらXMLで表示されるので、URLが正しいかどうか確かめることができる。

また、ドメインに参加している環境ではデフォルトの認証方式を使うことができる。つまり、ユーザーID/パスワードが要らない。

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.UseDefaultCredentials = true; // デフォルトでtrue
//service.Credentials = new WebCredentials("ユーザID", "パスワード");
service.AutodiscoverUrl("メール@アドレス.co.jp", url => true);

さらに、メールアドレスをActive Directoryから取ってくればメールアドレスも指定しなくてもよい。

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.UseDefaultCredentials = true; // デフォルトでtrue
//service.Credentials = new WebCredentials("ユーザID", "パスワード");
service.AutodiscoverUrl(UserPrincipal.Current.EmailAddress, url => true);

このとき、System.DirectoryServices.AccountManagement名前空間を参照している必要がある。

調べてないけど、ここまでやればメールとか連絡先とかにも簡単にアクセスできるでしょう。たぶん。

以上。簡単。