Can I read an Outlook (2003/2007) PST file in C#?

こ雲淡風輕ζ 提交于 2019-11-26 18:11:00

The Outlook Interop library is not just for addins. For example it could be used to write a console app that just reads all your Outlook Contacts. I am pretty sure that the standard Microsoft Outlook Interop library will let you read the mail - albeit it will probably throw a security prompt in Outlook that the user will have to click through.

EDITS: Actually implementing mail reading using Outlook Interop depends on what your definition of 'standalone' means. The Outlook Interop lib requires Outlook to be installed on the client machine in order to function.

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

As already mentioned in one of your linked SO questions, I'd also recommend using the Redemption library. I'm using it in a commercial application for processing Outlook mails and performing various tasks with them. It's working flawlessly and prevents showing up the annoying security alerts. It would mean using COM Interop, but that shouldn't be a problem.

There's a library in that package called RDO which is replacing the CDO 1.21, which lets you access PST files directly. Then it's as easy as writing (VB6 code):

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

I went through and did the refactoring for subfolders

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

You can use pstsdk.net: .NET port of PST File Format SDK library which is open source to read pst file without Outlook installed.

For those mentioning that they don't see the Stores collection:

The Stores collection was added in Outlook 2007. So, if you're using an interop library created from an earlier version (in an attempt to be version independent - this is ver common) then this would be why you won't see the Stores collection.

Your only options to get the Stores are to do one of the following:

  • Use an interop library for Outlook 2007 (this means your code won't work for earlier versions of Outlook).
  • Enumerate all top level folders with Outlook object model, extract the StoreID of each folder, and then use CDO or MAPI interfaces to get more information about each store.
  • Enumerate the InfoStores collection of CDO session object, and then use the fields collection of InfoStore object in order to get more information about each store.
  • Or (the hardest way) use extended MAPI call (In C++): IMAPISession::GetMsgStoresTable.

Another optional solution: NetPstExtractor

This is a .Net API to read Outlook PST file without Outlook installed.

You can find demo version here.

We are going to use this, to provide a solution that doesn't rely on outlook.

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

It is very expensive, but we hope that will lower development time and increase quality.

The MAPI API is what you are looking for. Unfortunately it is not available in .Net so I'm afraid you will have to resort to calling unmanaged code.

A quick Google reveals several wrappers available, maybe they work for you?

This might also be helpful: http://www.wischik.com/lu/programmer/mapi_utils.html

This .NET connector for Outlook might get you started.

Yes, with Independentsoft PST .NET is possible to read/export password protected and encrypted .pst file.

I found some resources directly from Microsoft which may be helpful for completing this task. A search on MSDN reveals the following.

Note that when you're adding a reference to Microsoft.Office.Interop.Outlook, the documentation insists that you do so via the .NET tab instead of the COM tab.

Really usefull code. If you have pst and store your messages in its root (without any directory), then you can use the following in method 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);
      }
 }

Yes you can use MS Access and then you either import your pst content or just link it (slow!).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!