2009-02-23 12 views
61

È possibile leggere un file .PST usando C#? Mi piacerebbe farlo come applicazione standalone, non come addin di Outlook (se possibile).Posso leggere un file PST di Outlook (2003/2007) in C#?

Se hanno visto otherSOquestionssimilar a questa menzione MailNavigator ma sto cercando di farlo a livello di codice in C#.

Ho visto lo spazio dei nomi Microsoft.Office.Interop.Outlook ma sembra essere solo per i componenti aggiuntivi di Outlook. LibPST sembra essere in grado di leggere i file PST, ma questo è in C (mi dispiace Joel, non ho learn C before graduating).

Qualsiasi aiuto sarebbe molto apprezzato, grazie!

EDIT:

Grazie a tutti per le risposte! Ho accettato la risposta di Matthew Ruston come risposta perché alla fine mi ha portato al codice che stavo cercando. Ecco un semplice esempio di quello che ho avuto modo di lavorare (Sarà necessario aggiungere un riferimento a 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; 
     } 
    } 
} 

Nota: Questo codice si presuppone che Outlook è installato e già configurato per l'utente corrente. Utilizza il profilo predefinito (puoi modificare il profilo predefinito andando a Mail nel Pannello di controllo). Un importante miglioramento di questo codice potrebbe essere quello di creare un profilo temporaneo da utilizzare al posto del Default, quindi distruggerlo una volta completato.

+0

Non avevo idea che i AddStores e l'elenco dei Negozi esistessero nell'API Outlook. Buon post! –

+0

Mi manca qualcosa? Perché non riesco ad accedere alla collezione Stores dell'outlook NS? Non è nell'intelligenza. –

+0

Hai incluso "l'uso di Microsoft.Office.Interop.Outlook;" nel tuo codice? –

risposta

23

La libreria di Outlook Interop non è solo per i componenti aggiuntivi. Ad esempio potrebbe essere usato per scrivere un'app console che legge solo tutti i tuoi contatti di Outlook. Sono abbastanza sicuro che la libreria standard di Microsoft Outlook Interop ti consentirà di leggere la posta, anche se probabilmente visualizzerà una richiesta di sicurezza in Outlook che l'utente dovrà fare clic.

MODIFICHE: L'implementazione effettiva della lettura della posta tramite Outlook Interop dipende dalla definizione di "standalone". La lib di Interop di Outlook richiede che Outlook sia installato sul computer client per funzionare.

// 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

Si può presumere che Outlook verrà installato sulla macchina, tuttavia, preferirei che non sia necessario aprire Outlook per leggere dal file PST. –

+0

Non è necessario che sia aperto. Il servizio di interoperabilità lo apre semplicemente sullo sfondo e lo chiude quando hai finito. –

+0

Ahhh, ok, suona bene. Vedo alcuni esempi su come usare questo per leggere Contatti e così via, ma mi interessa solo leggere i messaggi in un PST, non i Contatti al di fuori di un server Exchange. Sai, o hai un esempio, su questo? –

0

L'API MAPI è ciò che stai cercando. Sfortunatamente non è disponibile in .Net, quindi temo che dovrai ricorrere alla chiamata del codice non gestito.

Un veloce Google rivela diversi wrapper disponibili, forse funzionano per voi?

Questo potrebbe anche essere utile: http://www.wischik.com/lu/programmer/mapi_utils.html

0

This Il connettore .NET per Outlook consente di iniziare.

0

Sì, è possibile utilizzare MS Access e quindi è possibile importare il contenuto del PST o semplicemente collegarlo (lento!).

+0

Siamo spiacenti, non vedo come questo risponde alla mia domanda su come leggere un file PST in C#. Per favore spiega meglio. –

+0

Oh sì, mi dispiace, ho dimenticato la parte di C#, ma se riesci a controllare Access da C# potresti ancora andare in quel modo. Non testato! – Lorenzo

6

Come già menzionato in una delle tue domande SO collegate, ti consigliamo anche di utilizzare la libreria Redemption. Lo sto utilizzando in un'applicazione commerciale per l'elaborazione di mail di Outlook e l'esecuzione di varie attività con loro. Funziona in modo impeccabile e impedisce di mostrare i fastidiosi avvisi di sicurezza. Significherebbe usare COM Interop, ma questo non dovrebbe essere un problema.

C'è una libreria in quel pacchetto chiamato RDO che sta sostituendo il CDO 1.21, che consente di accedere direttamente ai file PST. Allora è facile come scrivere (codice 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

ho passato e ha fatto il refactoring per le sottocartelle

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

Che cos'è pstName? Hai già passato il file pstFilePath, perché hai bisogno di pstName? – HoKy22

0

Abbiamo intenzione di utilizzare questo, di fornire una soluzione che non si basa in prospettiva.

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

è molto costoso, ma speriamo che abbasserà i tempi di sviluppo e aumentare la qualità.

+0

+1 per questo suggerimento (è quello che ho usato). Anche il supporto tecnico è molto reattivo. – noonand

2

Per quelli di ricordare che non vedono la raccolta Stores:

La collezione Stores è stata aggiunta in Outlook 2007. Quindi, se si sta utilizzando una libreria di interoperabilità creato da una versione precedente (in un tentare di essere indipendenti dalla versione - questo è molto comune) allora questo sarebbe il motivo per cui non vedrai la collezione Stores.

Le uniche opzioni per ottenere i negozi sono a fare una delle seguenti:

  • Utilizzare una libreria di interoperabilità per Outlook 2007 (questo significa che il codice non funziona per le versioni precedenti di Outlook).
  • Enumerare tutte le cartelle di livello superiore con il modello di oggetti di Outlook, estrarre lo StoreID di ogni cartella e quindi utilizzare le interfacce CDO o MAPI per ottenere ulteriori informazioni su ogni archivio.
  • Enumerare la raccolta InfoStores dell'oggetto sessione CDO e quindi utilizzare la raccolta campi dell'oggetto InfoStore per ottenere ulteriori informazioni su ciascun negozio.
  • Oppure (il modo più difficile) utilizzare chiamata MAPI estesa (in C++): IMAPISession :: GetMsgStoresTable.
0

Sì, con Independentsoft PST .NET è possibile leggere/esportare file protetti con password e crittografati .pst.

0

Ho trovato alcune risorse direttamente da Microsoft che potrebbero essere utili per il completamento di questa attività. A search on MSDN rivela quanto segue.

Si noti che quando si aggiunge un riferimento a Microsoft.Office.Interop.Outlook, the documentation insiste che lo fa tramite la scheda .NET invece del COM scheda.

1

Un'altra soluzione opzionale: NetPstExtractor

Questa è un'API NET per leggere file PST di Outlook senza installato Outlook.

È possibile trovare la versione demo here.

0

codice davvero utile. Se avete PST e memorizzare i messaggi nella sua radice (senza alcuna directory), quindi è possibile utilizzare il seguente nel metodo di 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); 
     } 
} 
Problemi correlati