Question

Est-il possible de lire un fichier .PST en utilisant C #? Je voudrais faire comme une application autonome, et non comme un Outlook Addin (si cela est possible).

Si d'autres ont vu SO des questions similaire à cette MailNavigator mention mais je suis qui cherchent à le faire par programme en C #.

Je l'ai regardé Microsoft.Office.Interop l'espace de noms de .Outlook mais qui semble être juste pour addins Outlook. libpst semble pouvoir lire des fichiers PST, mais cela est en C (désolé Joel, je n'a pas apprendre le C avant d'être diplômé ).

Toute aide serait grandement appréciée, merci!

EDIT:

Merci à tous pour les réponses! J'ai accepté la réponse de Matthew Ruston comme la réponse parce qu'elle m'a finalement conduit au code que je cherchais. Voici un exemple simple de ce que je suis arrivé au travail (Vous devrez ajouter une référence à 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;
        }
    }
}

Note: Ce code suppose que Outlook est installé et déjà configuré pour l'utilisateur actuel. Il utilise le profil par défaut (vous pouvez modifier le profil par défaut en allant à la poste électronique dans le Panneau de configuration). Une amélioration majeure sur ce code serait de créer un profil temporaire à utiliser au lieu de la valeur par défaut, puis détruire une fois terminé.

Était-ce utile?

La solution

La bibliothèque d'Outlook Interop est pas seulement pour addins. Par exemple, il pourrait être utilisé pour écrire une application console qui se contente de lire tous vos contacts Outlook. Je suis assez sûr que la bibliothèque standard Microsoft Outlook Interop vous permettra de lire le courrier -. Mais il sera probablement lancer une invite de sécurité dans Outlook que l'utilisateur devra cliquer

EDITS : En fait la mise en œuvre de lecture de courrier utilisant Outlook Interop dépend de ce que votre définition de 'autonome' signifie. La lib Perspectives Interop nécessite Outlook pour être installé sur la machine cliente afin de fonctionner.

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

Autres conseils

Je suis passé par et fait le refactoring pour les sous-dossiers

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

Comme nous l'avons mentionné dans l'un de vos SO liés aux questions, je vous recommande également d'utiliser le Redemption . Je l'utilise dans une application commerciale pour le traitement de mails Outlook et effectuer diverses tâches avec eux. Il fonctionne parfaitement et empêche les montrant alertes de sécurité ennuyeux. Cela voudrait dire en utilisant COM Interop, mais cela ne devrait pas être un problème.

Il y a une bibliothèque dans ce paquet appelé RDO qui remplace la CDO 1.21, ce qui vous permet d'accéder à des fichiers PST directement. Ensuite, il est aussi facile que l'écriture (code 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

Vous pouvez utiliser pstsdk.net: port .NET de PST SDK Format de fichier bibliothèque qui est open source lire le fichier pst sans Outlook est installé.

Pour ceux de mentionner que ils ne voient pas la collection Boutiques:

dans Outlook 2007. La collecte a été ajouté magasins Donc, si vous utilisez une bibliothèque Interop créée à partir d'une version antérieure (dans une tentative d'être la version indépendante - ce ver est commun) alors ce serait la raison pour laquelle vous ne serez pas voir la collection magasins.

Vos seules options pour obtenir les magasins sont à faire une des opérations suivantes:

  • Utilisez une bibliothèque interop pour Outlook 2007 (cela signifie que votre code ne fonctionnera pas pour les versions antérieures d'Outlook).
  • Énumérer tous les dossiers de niveau supérieur avec le modèle objet Outlook, extraire le StoreID de chaque dossier, puis utiliser les interfaces CDO ou MAPI pour obtenir plus d'informations sur chaque magasin.
  • Énumérer la collection infostores de l'objet de la session CDO, puis utilisez la collection de champs d'objet InfoStore afin d'obtenir plus d'informations sur chaque magasin.
  • Ou (la manière la plus dure) utilisent appel MAPI étendu (en C ++): IMAPISession :: GetMsgStoresTable.

Une autre solution en option: NetPstExtractor

Ceci est une API .NET pour lire le fichier PST d'Outlook sans Outlook est installé.

Vous pouvez trouver la version démo ici.

Nous allons utiliser, pour fournir une solution qui ne repose pas sur les perspectives.

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

Il est très cher, mais nous espérons que abaissera le temps de développement et d'accroître la qualité.

L'API MAPI est ce que vous recherchez. Malheureusement, il est disponible en .Net, donc je suis peur que vous devrez recourir à l'appel de code non managé.

Un rapide sur Google révèle plusieurs wrappers disponibles, peut-être qu'ils travaillent pour vous?

Cela pourrait aussi être utile: http://www.wischik.com/lu /programmer/mapi_utils.html

Ce connecteur .NET pour Outlook peut vous aider à démarrer.

Oui, avec Independentsoft PST .NET est possible de lire / mot de passe d'exportation fichier .pst protégé et crypté.

scroll top