Domanda

E 'possibile leggere un file PST utilizzando C #? Vorrei fare questo come applicazione autonoma, non come un componente aggiuntivo di Outlook (se possibile).

Se aver visto altro SO domande simile a questo MailNavigator ma sono cercando di farlo a livello di codice in C #.

Ho guardato il Microsoft.Office.Interop .Outlook spazio dei nomi, ma che sembra essere solo per i componenti aggiuntivi di Outlook. LibPST sembra essere in grado di leggere i file PST, ma questo è in C (scusate Joel, ho non ha imparare il C prima della laurea ).

Qualsiasi aiuto sarebbe molto apprezzato, grazie!

Modifica

Grazie a tutti per le risposte! Ho accettato la risposta di Matteo Ruston come la risposta, perché in ultima analisi, 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 presuppone che Outlook è installato e già configurato per l'utente corrente. Esso utilizza il profilo di default (è possibile modificare il profilo predefinito andando a Mail nel Pannello di controllo). Un miglioramento importante su questo codice sarebbe quello di creare un profilo temporaneo da utilizzare al posto del difetto, poi distruggerla una volta completato.

È stato utile?

Soluzione

La biblioteca di Outlook Interop non è solo per i componenti aggiuntivi. Per esempio potrebbe essere usato per scrivere una console app che legge solo tutti i tuoi contatti di Outlook. Sono abbastanza sicuro che la libreria standard di Microsoft Outlook Interop vi permetterà di leggere la posta elettronica -. Anche se sarà probabilmente lanciare una richiesta di protezione di Outlook che l'utente dovrà scegliere attraverso

EDITS : In realtà implementare la lettura di posta elettronica utilizzando Outlook Interop dipende da ciò che la tua definizione di 'stand-alone' significa. Il lib Outlook Interop richiede Outlook per essere installato sulla macchina client per poter 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();
    }
}
}

Altri suggerimenti

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

Come già accennato in una delle vostre questioni legate così, mi piacerebbe anche consiglia di utilizzare il Redenzione biblioteca. Lo sto usando in un'applicazione commerciale per l'elaborazione elettronica di Outlook ed eseguire vari compiti con loro. Sta funzionando senza problemi e impedisce mostrando gli allarmi sicurezza fastidioso. Significherebbe utilizza interoperabilità COM, ma questo non dovrebbe essere un problema.

C'è una biblioteca in quel pacchetto chiamato RDO che sta sostituendo il CDO 1.21, che consente di accedere direttamente i 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

È possibile utilizzare pstsdk.net: porta NET di PST File Format SDK biblioteca che è open source per leggere il file PST senza installato Outlook.

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 (nel tentativo di essere la versione indipendente - questo è ver comune), allora questo sarebbe il motivo per cui non lo farà consultare la raccolta Stores.

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

  • 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 primo livello con il modello a oggetti di Outlook, estrarre lo StoreID di ogni cartella, e quindi utilizzare le interfacce CDO o MAPI per avere maggiori informazioni su ogni negozio.
  • enumerare la raccolta Infostores di CDO oggetto di sessione, e quindi utilizzare la raccolta campi di oggetto InfoStore al fine di ottenere ulteriori informazioni su ogni negozio.
  • Or (il modo più duro) uso prolungato chiamata MAPI (in C ++): IMAPISession :: GetMsgStoresTable.

Un'altra soluzione opzionale: NetPstExtractor

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

È possibile trovare la versione demo qui.

Abbiamo intenzione di utilizzare questo, per fornire una soluzione che non si basa su prospettive.

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

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

L'API MAPI è quello che stai cercando. Purtroppo non è disponibile in Net così temo si dovrà ricorrere a chiamare codice non gestito.

Un rapido Google rivela diversi involucri a disposizione, forse funzionano per voi?

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

Questo connettore .NET per Outlook potrebbe iniziare.

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

Ho trovato alcune risorse direttamente da Microsoft che possono essere utili per il completamento di questa operazione. Un cercare MSDN rivela quanto segue.

Si noti che quando si aggiunge un riferimento a Microsoft.Office.Interop.Outlook, la documentazione insiste sul fatto che lo fa tramite la scheda .NET anziché la scheda COM.

Codice veramente utile. Se avete PST e memorizzare i messaggi nella sua radice (senza alcuna directory), quindi è possibile utilizzare il seguente metodo in 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);
      }
 }

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top