Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Is it possible to read a .PST file using C#? I would like to do this as a standalone application, not as an Outlook addin (if that is possible).

If have seen other SO questions similar to this mention MailNavigator but I am looking to do this programmatically in C#.

I have looked at the Microsoft.Office.Interop.Outlook namespace but that appears to be just for Outlook addins. LibPST appears to be able to read PST files, but this is in C (sorry Joel, I didn't learn C before graduating).

Any help would be greatly appreciated, thanks!

EDIT:

Thank you all for the responses! I accepted Matthew Ruston's response as the answer because it ultimately led me to the code I was looking for. Here is a simple example of what I got to work (You will need to add a reference to 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: This code assumes that Outlook is installed and already configured for the current user. It uses the Default Profile (you can edit the default profile by going to Mail in the Control Panel). One major improvement on this code would be to create a temporary profile to use instead of the Default, then destroy it once completed.

like image 407
Andy May Avatar asked Feb 23 '09 15:02

Andy May


People also ask

How can I read a PST file without Outlook?

If you want to open a PST file without Outlook, you need to open your PST file in Gmail using the Google App Migration(GWMMO) tool. First, go to the Google Workspace Migration for Microsoft Outlook tool's official website and download and install it on your computer.


Video Answer


2 Answers

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();     } } } 
like image 104
Matthew Ruston Avatar answered Sep 29 '22 08:09

Matthew Ruston


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);         }     } 
like image 42
Tom Kidd Avatar answered Sep 29 '22 09:09

Tom Kidd