76 votes

Puis-je lire un fichier PST Outlook (2003/2007) en C# ?

Est-il possible de lire un fichier .PST en utilisant C# ? J'aimerais le faire en tant qu'application autonome, et non en tant qu'addin Outlook (si c'est possible).

Si vous avez vu autres SO questions similaire à cette mention MailNavigator mais je cherche à le faire de manière programmatique en C#.

J'ai examiné le Microsoft.Office.Interop.Outlook mais il semble que ce soit uniquement pour les modules complémentaires d'Outlook. LibPST semble pouvoir lire les fichiers PST, mais c'est en C (désolé Joel, je ne l'ai pas fait). apprendre le C avant d'être diplômé ).

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

EDIT :

Merci à tous pour vos réponses ! J'ai accepté la réponse de Matthew Ruston comme réponse parce qu'elle m'a finalement conduit au code que je cherchais. Voici un exemple simple de ce que j'ai réussi à faire fonctionner (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;
        }
    }
}

Remarque : Ce code suppose qu'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 dans Courrier dans le Panneau de configuration). Une amélioration majeure de ce code serait de créer un profil temporaire à utiliser à la place du profil par défaut, puis de le détruire une fois terminé.

0 votes

Je n'avais aucune idée que les listes AddStores et Stores existaient dans l'API Outlook. Bon article !

0 votes

Ai-je oublié quelque chose ? Pourquoi ne puis-je pas accéder à la collection Stores de outlookNS ? Ce n'est pas dans intellisense.

0 votes

Avez-vous inclus "using Microsoft.Office.Interop.Outlook ;" dans votre code ?

30voto

Matthew Ruston Points 2319

La bibliothèque Outlook Interop n'est pas réservée aux modules complémentaires. Par exemple, elle pourrait être utilisée pour écrire une application console qui lit simplement tous vos contacts Outlook. Je suis presque sûr que la bibliothèque standard Microsoft Outlook Interop vous permettra de lire le courrier - bien qu'elle lancera probablement une invite de sécurité dans Outlook sur laquelle l'utilisateur devra cliquer.

EDITS : L'implémentation de la lecture du courrier à l'aide d'Outlook Interop dépend de votre définition du terme "autonome". La librairie Outlook Interop nécessite l'installation d'Outlook sur la machine cliente pour 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();
    }
}
}

0 votes

On peut supposer qu'Outlook sera installé sur la machine, mais je préférerais qu'il ne soit pas nécessaire d'avoir Outlook ouvert pour lire le fichier PST.

0 votes

Il n'est pas nécessaire qu'il soit ouvert. La librairie interop l'ouvre simplement en arrière-plan et la ferme lorsque vous avez terminé.

0 votes

Ahhh, ok, ça a l'air bien. Je vois quelques exemples d'utilisation pour lire des contacts et autres, mais je ne suis intéressé que par la lecture de messages dans un PST, pas de contacts sur un serveur Exchange. Est-ce que vous savez, ou avez-vous un exemple, à ce sujet ?

8voto

Schnapple Points 6117

J'ai procédé à la refonte des 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);
        }
    }

0 votes

Qu'est-ce que pstName ? Vous passez déjà le pstFilePath, pourquoi avez-vous besoin de pstName ?

6voto

MicSim Points 12980

Comme je l'ai déjà mentionné dans l'une de vos questions sur le SO, je recommanderais également d'utiliser l'option La rédemption bibliothèque. Je l'utilise dans une application commerciale pour traiter les courriers Outlook et effectuer diverses tâches avec eux. Elle fonctionne parfaitement et évite d'afficher les alertes de sécurité gênantes. Il faudrait utiliser COM Interop, mais cela ne devrait pas poser de problème.

Ce paquet contient une bibliothèque appelée RDO qui remplace la CDO 1.21 et qui vous permet d'accéder directement aux fichiers PST. Il suffit alors d'écrire (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

2voto

Ryan Farley Points 7916

Pour ceux qui mentionnent qu'ils ne voient pas la collection Stores :

La collection Stores a été ajoutée dans Outlook 2007. Par conséquent, si vous utilisez une bibliothèque interop créée à partir d'une version antérieure (dans le but d'être indépendant de la version - ce qui est très courant), c'est la raison pour laquelle vous ne verrez pas la collection Stores.

Vos seules options pour obtenir les Stores sont les suivantes :

  • Utilisez une bibliothèque interop pour Outlook 2007 (cela signifie que votre code ne fonctionnera pas pour les versions antérieures d'Outlook).
  • Enumérer tous les dossiers de premier niveau avec le modèle d'objet Outlook, extraire le StoreID de chaque dossier, puis utiliser les interfaces CDO ou MAPI pour obtenir plus d'informations sur chaque magasin.
  • Enumérer la collection de dépôts de données de l'objet de session CDO, puis utiliser la collection de champs de l'objet de dépôt de données afin d'obtenir plus d'informations sur chaque dépôt.
  • Ou (la méthode la plus difficile) utiliser un appel MAPI étendu (en C++) : IMAPISession::GetMsgStoresTable.

2voto

Saqib Razzaq Points 603

Vous pouvez également essayer Aspose.Network for .NET pour lire et extraire les fichiers msg du fichier Outlook PST. Visitez le site http://www.aspose.com/documentation/.net-components/aspose.network-for-.net/read-outlook-pst-file-and-get-folders-and-subfolders-information.html pour plus d'informations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X