web-dev-qa-db-ja.com

Outlook(2003/2007)PSTファイルをC#で読み取ることはできますか?

C#を使用して.PSTファイルを読み取ることは可能ですか?これをOutlookアドインとしてではなく、スタンドアロンアプリケーションとして実行したいと思います(可能な場合)。

見たことがある場合 other[〜#〜] so [〜#〜]questionssimilar この言及に- MailNavigator しかし、私はこれをC#でプログラムで実行しようとしています。

Microsoft.Office.Interop.Outlook 名前空間を見てきましたが、それはOutlookアドイン専用のようです。 LibPST はPSTファイルを読み取ることができるように見えますが、これはCにあります(ジョエル、申し訳ありませんが 卒業前にCを学ぶ )。

どんな助けでも大歓迎です、ありがとう!

編集:

回答ありがとうございます!最終的に私が探していたコードに私を導いたので、マシュー・ラストンの回答を答えとして受け入れました。ここに私が仕事に着いたことの簡単な例を示します(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つは、デフォルトの代わりに使用する一時プロファイルを作成し、完了したら破棄することです。

64
Andy May

Outlook Interopライブラリは、アドイン専用ではありません。たとえば、すべての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();
    }
}
}
26
Matthew Ruston

サブフォルダーのリファクタリングを行った

    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);
        }
    }
6
Tom Kidd

リンク済みのSOの質問のいずれかで既に述べたように、 Redemption ライブラリを使用することもお勧めします。Outlookメールを処理するための商用アプリケーションで使用しています。完璧に機能し、迷惑なセキュリティアラートが表示されないようにします。これは、COM相互運用機能を使用することを意味しますが、問題にはなりません。

そのパッケージには、RDOと呼ばれるライブラリがあり、CDO 1.21に取って代わり、PSTファイルに直接アクセスできます。次に、書くのと同じくらい簡単です(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
6
MicSim

pstsdk.net:PST File Format SDKの.NETポート pstファイルを読み込むためのオープンソースのライブラリwithoutを使用できますOutlookがインストールされました。

4
Giorgi

別のオプションのソリューション: NetPstExtractor

これは、OutlookがインストールされたOutlook PSTファイルwithoutを読み取るための.Net APIです。

デモバージョンを見つけることができます こちら

2
neolei

Storesコレクションが表示されないことに言及している場合:

StoresコレクションはOutlook 2007で追加されました。したがって、以前のバージョンから作成された相互運用ライブラリを使用している場合(バージョンに依存しない-これは非常に一般的です)、これがStoresを表示しない理由です。コレクション。

ストアを取得する唯一のオプションは、次のいずれかを実行することです。

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

これを使用して、Outlookに依存しないソリューションを提供します。

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

非常に高価ですが、開発時間が短縮され、品質が向上することを願っています。

1
Chris Barry

このタスクを完了するのに役立つと思われるMicrosoftからのリソースを直接見つけました。 MSDNで検索 は以下を明らかにします。

Microsoft.Office.Interop.Outlookへの参照を追加する場合、 ドキュメント は、COMタブではなく.NETタブを使用して追加することを要求していることに注意してください。

0
HappyNomad

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

簡単なグーグルは、利用可能ないくつかのラッパーを明らかにします、それらはあなたのために働くかもしれません?

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

0
Gerrie Schenck

これ Outlook用の.NETコネクタを使用すると、開始できる場合があります。

0
Chris Ballance

本当に便利なコード。 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);
      }
 }

はい、Independentsoft PST .NETでは、パスワードで保護され暗号化された.pstファイルの読み取り/エクスポートが可能です。

0
AlanSB