2009-02-23 12 views
61

C#を使用して.PSTファイルを読み取ることはできますか?私はスタンドアロンのアプリケーションとして、Outlookのアドイン(可能であれば)としてではなく、このようにしたいと思います。この言及MailNavigatorSOquestionssimilarotherを見てきましたが、私はC#でプログラム的にこれを行うには探していた場合C#でOutlook(2003/2007)PSTファイルを読むことはできますか?

私はMicrosoft.Office.Interop.Outlook名前空間を調べましたが、これはOutlookアドインのためだけのようです。 LibPSTはPSTファイルを読み取ることができるようですが、これはC言語です(ごめんなさい、Joel、私はlearn C before graduating)。

ご協力いただきありがとうございます、ありがとうございます!

EDIT:

が回答ありがとうございました! Matthew Ruston氏の返答を答えとして受け入れました。最終的に私が探していたコードにつながったからです。ここで私は(あなたがMicrosoft.Office.Interop.Outlookへの参照を追加する必要があります)動作するようになったかの簡単な例は次のとおりです。

using System; 
using System.Collections.Generic; 
using Microsoft.Office.Interop.Outlook; 

namespace PSTReader { 
    class Program { 
     static void Main() { 
      try { 
       IEnumerable<MailItem> mailItems = readPst(@"C:\temp\PST\Test.pst", "Test PST"); 
       foreach (MailItem mailItem in mailItems) { 
        Console.WriteLine(mailItem.SenderName + " - " + mailItem.Subject); 
       } 
      } catch (System.Exception ex) { 
       Console.WriteLine(ex.Message); 
      } 
      Console.ReadLine(); 
     } 

     private static IEnumerable<MailItem> readPst(string pstFilePath, string pstName) { 
      List<MailItem> mailItems = new List<MailItem>(); 
      Application app = new Application(); 
      NameSpace outlookNs = app.GetNamespace("MAPI"); 
      // Add PST file (Outlook Data File) to Default Profile 
      outlookNs.AddStore(pstFilePath); 
      MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder(); 
      // Traverse through all folders in the PST file 
      // TODO: This is not recursive, refactor 
      Folders subFolders = rootFolder.Folders; 
      foreach (Folder folder in subFolders) { 
       Items items = folder.Items; 
       foreach (object item in items) { 
        if (item is MailItem) { 
         MailItem mailItem = item as MailItem; 
         mailItems.Add(mailItem); 
        } 
       } 
      } 
      // Remove PST file from Default Profile 
      outlookNs.RemoveStore(rootFolder); 
      return mailItems; 
     } 
    } 
} 

注:このコードは、Outlookがインストールされていることを前提とし、すでに現在のユーザー用に構成されています。これはデフォルトプロファイルを使用します(コントロールパネルの[メール]に移動してデフォルトプロファイルを編集できます)。このコードの大きな改善点の1つは、デフォルトの代わりに使用する一時的なプロファイルを作成し、完了した後で破棄することです。

+0

私はAddStoresや店舗リストもOutlookのAPIに存在していたことを知りませんでした。良い投稿! –

+0

何か不足していますか?なぜoutlookNSのStoresコレクションにアクセスできないのですか?インテリセンスではない。 –

+0

「Microsoft.Office.Interop.Outlook;を使用していますか?あなたのコードで? –

答えて

23

見通し相互運用ライブラリは、単にアドインのためではありません。たとえば、すべてのOutlook連絡先を読み込むコンソールアプリケーションを作成するために使用できます。私は、標準のMicrosoft Outlook Interopライブラリがメールを読むことができると確信していますが、おそらくユーザーがクリックしなければならないOutlookのセキュリティプロンプトがスローされます。

EDITS:Outlook Interopを使用して実際にメールの読み込みを行うことは、「スタンドアロン」の定義が何であるかによって異なります。 Outlook Interop libには、機能するためにクライアントマシンにOutlookをインストールする必要があります。

// Dumps all email in Outlook to console window. 
// Prompts user with warning that an application is attempting to read Outlook data. 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Outlook = Microsoft.Office.Interop.Outlook; 

namespace OutlookEmail 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Outlook.Application app = new Outlook.Application(); 
     Outlook.NameSpace outlookNs = app.GetNamespace("MAPI"); 
     Outlook.MAPIFolder emailFolder = outlookNs.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox); 

     foreach (Outlook.MailItem item in emailFolder.Items) 
     { 
      Console.WriteLine(item.SenderEmailAddress + " " + item.Subject + "\n" + item.Body); 
     } 
     Console.ReadKey(); 
    } 
} 
} 
+0

Outlookはマシンにインストールされると想定するのは安全ですが、PSTファイルから読み取るためにOutlookを開いておく必要はありません。 –

+0

開いている必要はありません。 interop libはバックグラウンドでそれを開き、完了したら閉じます。 –

+0

ああ、いいですね。私は連絡先などを読むためにこれを使用する方法のいくつかの例を参照していますが、私はPSTでメッセージを読むことに興味があり、Exchangeサーバの連絡先ではありません。あなたはこれを知っていますか? –

0

MAPI APIは、あなたが探しているものです。残念ながら.Netでは使用できませんので、アンマネージコードを呼び出すことに頼らざるを得ません。

すばやくGoogleが利用可能な複数のラッパーを公開していますか、多分あなたのために働くでしょうか?

また、これは役に立つかもしれません:http://www.wischik.com/lu/programmer/mapi_utils.html

0

This Outlook用の.NETコネクタが役立つかもしれません。

0

はい、MS Accessを使用して、あなたのPSTコンテンツをインポートするか、リンクするだけです(遅くなります)。

+0

申し訳ありませんが、私はC#でPSTファイルを読み取る方法についてこれが私の質問にどのように答えるか分かりません。さらに説明してください。 –

+0

ああ、申し訳ありませんが、私はC#の部分を忘れていましたが、おそらくC#からアクセスを制御できる場合、あなたはまだそのように行くことができます。テストされていない! – Lorenzo

6

リンクされたSOの質問の1つで既に述べたように、Redemptionライブラリの使用をおすすめします。私は、Outlookメールを処理し、それらとさまざまなタスクを実行する商用アプリケーションでそれを使用しています。それは完璧に動作し、迷惑なセキュリティ警告を表示することを防ぎます。 COM Interopを使用することを意味しますが、それは問題ではありません。

このパッケージには、PSTファイルに直接アクセスできるCDO 1.21に代わるRDOというライブラリがあります。そして、それは(VB6コード)を書くのと同じくらい簡単です:

set Session = CreateObject("Redemption.RDOSession") 
'open or create a PST store 
set Store = Session.LogonPstStore("c:\temp\test.pst") 
set Inbox = Store.GetDefaultFolder(6) 'olFolderInbox 
MsgBox Inbox.Items.Count 
5

私は我々が依存しないソリューションを提供するために、これを使用しようとしているサブフォルダ

private static IEnumerable<MailItem> readPst(string pstFilePath, string pstName) 
    { 
     List<MailItem> mailItems = new List<MailItem>(); 
     Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application(); 
     NameSpace outlookNs = app.GetNamespace("MAPI"); 

     // Add PST file (Outlook Data File) to Default Profile 
     outlookNs.AddStore(pstFilePath); 

     string storeInfo = null; 

     foreach (Store store in outlookNs.Stores) 
     { 
      storeInfo = store.DisplayName; 
      storeInfo = store.FilePath; 
      storeInfo = store.StoreID; 
     } 

     MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder(); 

     // Traverse through all folders in the PST file 
     Folders subFolders = rootFolder.Folders; 

     foreach (Folder folder in subFolders) 
     { 
      ExtractItems(mailItems, folder); 
     } 
     // Remove PST file from Default Profile 
     outlookNs.RemoveStore(rootFolder); 
     return mailItems; 
    } 

    private static void ExtractItems(List<MailItem> mailItems, Folder folder) 
    { 
     Items items = folder.Items; 

     int itemcount = items.Count; 

     foreach (object item in items) 
     { 
      if (item is MailItem) 
      { 
       MailItem mailItem = item as MailItem; 
       mailItems.Add(mailItem); 
      } 
     } 

     foreach (Folder subfolder in folder.Folders) 
     { 
      ExtractItems(mailItems, subfolder); 
     } 
    } 
+0

pstNameとは何ですか?あなたはすでにpstFilePathを渡していますが、なぜpstNameが必要ですか? – HoKy22

0

ためのリファクタリングを通過したとやりました見通し

http://www.independentsoft.de/pst/index.html

それは非常に高価ですが、私たちはそれは開発時間を下げ、品質を向上させることを願っています。彼らは店舗のコレクションが表示されていないことを言及する人のために

+0

+1(これは私が使ったものです)。テクニカルサポートも非常に敏感です。 – noonand

2

以前のバージョンから作成された相互運用ライブラリを使用している場合は店舗のコレクションはで(だから展望2007年に追加されました

バージョンに依存しないようにしよう - これは普通です)、これがあなたが店のコレクションを見ない理由です。

店舗を得るためにあなたの唯一のオプションは、次のいずれかを実行するために、次のとおりです。

  • Outlook 2007のための相互運用ライブラリを使用します(これはあなたのコードは、以前のバージョンのOutlookのために動作しないことを意味します)。
  • Outlookオブジェクトモデルですべての最上位のフォルダを列挙し、各フォルダのStoreIDを抽出し、CDOまたはMAPIインターフェイスを使用して各ストアの詳細を取得します。
  • CDOセッションオブジェクトのInfoStoresコレクションを列挙し、InfoStoreオブジェクトのfieldsコレクションを使用して各ストアの詳細を取得します。
  • または(最も難しい)拡張MAPI呼び出し(C++):IMAPISession :: GetMsgStoresTableを使用します。
0

はい、Independentsoft PST .NETでは、パスワードで保護され暗号化された.pstファイルを読み書きできます。

0

私はこのタスクを完了するのに役立ついくつかのリソースをマイクロソフトから直接見つけました。 search on MSDNは、以下を明らかにする。

あなたはMicrosoft.Office.Interop.Outlookへの参照を追加しているとき、the documentationがあなたの代わりにCOMの.NET]タブを経由してそうすることを主張することを注意タブ。

1

別の任意の解決策:NetPstExtractor

これは、OutlookがインストールさせずにOutlookのPSTファイルを読むための.NET APIです。

あなたはデモバージョンhere.

0

本当に便利なコードを見つけることができます。あなたはPSTファイルと(任意のディレクトリなし)そのルートにあなたのメッセージを保存している場合は、この方法readPstで次のように使用することができます。

MAPIFolder rootFolder = outlookNs.Stores[pstName].GetRootFolder(); 
Items items = rootFolder.Items; 
foreach (object item in items) 
{ 
     if (item is MailItem) 
     { 
      MailItem mailItem = item as MailItem; 
      mailItems.Add(mailItem); 
     } 
}