2009-02-23 15 views
61

C# kullanarak bir .PST dosyasını okumak mümkün mü? Bunu, bir Outlook eklentisi olarak değil (eğer mümkünse) bağımsız bir uygulama olarak yapmak isterim. Bu söz MailNavigator için SOquestionssimilarother gördük ama C# programlı bunu arıyorum varsaC# içinde bir Outlook (2003/2007) PST dosyasını okuyabilir miyim?

.

Microsoft.Office.Interop.Outlook ad alanına baktım, ancak bu yalnızca Outlook eklentileri için görünüyor. LibPST, PST dosyalarını okuyabiliyor gibi görünüyor, ancak bu C (üzgün Joel, ben learn C before graduating kullanmamıştım).

Herhangi bir yardım çok takdir edilecektir, teşekkürler!

DÜZENLEME:

yanıtlar için teşekkür ederiz! Matthew Ruston'un cevabını cevap olarak kabul ettim çünkü sonuçta beni aradığım koda yönlendirdi. Burada (Microsoft.Office.Interop.Outlook bir başvuru eklemeniz gerekir) çalışmaya ne var basit bir örneğidir:

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; 
     } 
    } 
} 

Not: Bu kod, Outlook yüklü olduğunu varsayar ve zaten geçerli kullanıcı için yapılandırılmış. Varsayılan Profili kullanır (Denetim Masası'ndaki Posta'ya giderek varsayılan profili düzenleyebilirsiniz). Bu kod üzerinde önemli bir gelişme, Varsayılan yerine kullanmak için geçici bir profil oluşturmak, ardından tamamlandığında yok etmek olacaktır.

+0

Ben AddStores ve Mağazalar listesi bile Outlook API var olduğunu bilmiyordum. İyi yazı! –

+0

Bir şey mi eksik? Neden outlookNS'un Mağazalar koleksiyonuna erişemiyorum? Bu intellisense içinde değil. –

+0

'Microsoft.Office.Interop.Outlook'u kullanarak dahil ettiniz mi?' senin kodunda –

cevap

23

Outlook Interop'un kütüphane sadece eklentileri için değil. Örneğin, tüm Outlook Kişilerinizi okuyan bir konsol uygulaması yazmak için kullanılabilir. Standart Microsoft Outlook Interop kütüphanesinin postayı okumanıza izin vereceğinden oldukça eminim - muhtemelen Outlook'ta kullanıcının tıklaması gereken bir güvenlik uyarısı atacaktır.

EDITS: Outlook Interop'u kullanarak posta okumayı gerçek anlamda uygulamak, 'bağımsız' tanımınızın ne anlama geldiğine bağlıdır. Outlook ınterrop lib, işlevini yerine getirmek için Outlook'un istemci makineye yüklenmesini gerektirir.

// 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'un makineye yükleneceğini varsayabiliriz, ancak Outlook'un PST dosyasından okunması için açık olması gerekmez. –

+0

Açık olması gerekmiyor. Interop lib sadece arka planda açar ve bittiğinde onu kapatır. –

+0

Ahhh, tamam, kulağa hoş geliyor. Bunu, Kişiler'i ve benzerlerini okumak için nasıl kullanacağım için bazı örnekler görüyorum, ancak sadece bir Exchange sunucusundaki kişileri değil, bir PST'deki iletileri okumakla ilgileniyorum. Bunun hakkında bir örnek var mı, yoksa bir örnek var mı? –

0

MAPI API aradığınız şeydir. Maalesef .Net'te mevcut değil. Korkarım ki, yönetilmeyen kodu çağırmaktan kaçınmalısınız.

Hızlı bir Google, birkaç paketin mevcut olduğunu gösterir, belki sizin için çalışırlar?

Bu aynı zamanda yararlı olabilir: http://www.wischik.com/lu/programmer/mapi_utils.html

0

This Outlook için .NET bağlacı başlatılabilir.

0

Evet MS Access'i kullanabilir ve daha sonra ya pst içeriğinizi içe aktarabilir ya da bağlayabilirsiniz (yavaş!).

+0

Maalesef, bu sorunun C# dilinde PST dosyasını nasıl okuyacağımı nasıl yanıtladığını göremiyorum. Lütfen daha detaylı anlatın. –

+0

Oh evet üzgünüm, C# parçasını unutmuştum, ama eğer C# 'dan Erişim'i kontrol edebilecek olursan hala bu şekilde gidebilirsin. Test edilmemiş! – Lorenzo

6

Bağlantılı SO sorularınızdan birinde belirtildiği gibi, Redemption kitaplığını kullanmanızı da öneririm. Outlook postalarını işlemek ve onlarla çeşitli görevleri gerçekleştirmek için ticari bir uygulamada kullanıyorum. Kusursuz çalışıyor ve can sıkıcı güvenlik uyarılarını göstermeyi engelliyor. COM Interop kullanmak anlamına gelir, ancak bu bir sorun olmamalıdır.

Bu pakette, PST dosyalarına doğrudan erişmenizi sağlayan CDO 1.21'in yerini alan RDO adlı bir kitaplık var. Ben geçti ve alt

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); 
     } 
    } 
5

: Sonra (VB6 kod) yazmak kadar kolay görünümde.

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

Çok pahalı, ama biz bu geliştirme zamanı ve artış kalitesini düşürür umuyoruz. onlar Mağazalar koleksiyon görmüyorum söz edenler için

+0

pstName nedir? PstFilePath'ı zaten geçtiniz, neden pstName'a ihtiyacınız var? Bu öneri için – HoKy22

0

Biz itimat etmeyen bir çözüm sağlamak için, bu kullanacağız için üstlenmeden yaptılar

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 
+0

+1 (kullandığım şey). Teknik destek de çok duyarlı. – noonand

2

: daha önceki bir sürümünde oluşturulmuş bir birlikte çalışma kitaplığı kullanıyorsanız saklar toplama bir in (So Outlook 2007'de eklenmiş

Versiyondan bağımsız olmaya çalışın - bu çok yaygındır), bu yüzden Mağazalar koleksiyonunu görmeyeceksiniz. Mağazaları almak için

Yalnızca seçeneklerinizi aşağıdakilerden birini yapın şunlardır:

  • Outlook 2007 için bir birlikte çalışma kitaplığı kullanın (bu kod Outlook'un önceki sürümleri için çalışmaz anlamına gelir).
  • Tüm üst düzey klasörleri Outlook nesne modeli ile numaralandırın, her bir klasörün StoreID değerini alın ve sonra her bir mağaza hakkında daha fazla bilgi almak için CDO veya MAPI arabirimlerini kullanın.
  • CDO oturum nesnesinin InfoStores koleksiyonunu numaralandırın ve ardından her mağaza hakkında daha fazla bilgi almak için InfoStore nesnesinin alan koleksiyonunu kullanın.
  • Veya (en zor yol) genişletilmiş MAPI çağrısı (C++) kullanın: IMAPISession :: GetMsgStoresTable.
0

Evet, Independentsoft PST .NET ile parola korumalı ve şifreli .pst dosyasını okumak/vermek mümkündür.

0

Bu görevi tamamlamak için yardımcı olabilecek bazı Microsoft'tan doğrudan kaynak buldum. Bir search on MSDN, aşağıdakileri gösterir. Eğer Microsoft.Office.Interop.Outlook başvuru, the documentation eklerken COM yerine NET sekmesi aracılığıyla bunu ısrar olduğunu

Not sekmesi.

1

İsteğe bağlı başka bir çözüm: Outlook yüklü NetPstExtractor

Bu Outlook PST dosyası okumak için bir NET API olmadan.

Sen demo sürüm here.

0

Gerçekten yararlı kodunu bulabilirsiniz. Eğer pst ve (herhangi bir dizine olmadan), kök mesajlarınızı saklamak varsa, o zaman yöntem readPst aşağıdaki kullanabilirsiniz:

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); 
     } 
} 
İlgili konular