Click here to Skip to main content
Click here to Skip to main content

Outlook Email Extractor

, 11 Oct 2007 Ms-PL
Rate this:
Please Sign up or sign in to vote.
Extract a PST file through .NET

Introduction

Sooner or later, we all have to face the problem of an overloaded number of emails and mail attachments to our Outlook account. Some of them are important to our business, as well, so we really need to save these email messages and attachments. Manually saving messages and attachments is a time-consuming process. So, we need to export these emails and other Outlook items to PST (Personal Storage File) files. The PST file is an archive for all items in an Outlook account. So, after exporting this file to storage media, we can process the PST file to get loose data and messages out of it. In this article, I am going to show you how we can extract this PST file through a .NET application.

Background

Basically, to deal with Outlook in a .NET application, we need an interface named MAPI. MAPI stands for Messaging Application Programming Interface and is provided by Microsoft for Outlook programming. Using MAPI, we can access folders like Inbox, Drafts, Sent Items and so on that reside in a PST file. We can even create sessions and namespace to fetch items from Outlook or, say, from a PST file. Currently, MAPI is the only namespace provided by Microsoft to extract PST files. For further information on MAPI, I suggest newbies visit the relevant MSDN article.

Using the Code

When you deal with Outlook objects in your .NET application, you must add a reference to the Microsoft Outlook 10.0 or 11.0 object library, whichever you have available. Note that you can find references to this library under the COM tab in the Add Reference dialog box. This is just because we are accessing the unmanaged world -- say, Microsoft Outlook -- from the managed world, say, the .NET Framework.

You can optionally create an Interop Assembly type library using the tlbimp command from the .NET command prompt. Adding this reference to your application gives you access to Outlook objects in you application. Additionally, you have to add a reference to the MAPI.dll file, which will help you create MAPI objects in your application. Let's have a look at the code that extracts a PST file:

'Create Outlook object
Dim objApp As New Outlook.Application 
'Create reference to Namespace to be used from outlook object
Dim objNsp As Outlook.NameSpace
'Get MAPI Namespace object from outlook object
objNsp = objApp.GetNamespace("MAPI")

'Logon to this session with Username and password.Outlook is 
'default account for Outlook
objNsp.Session.Logon("outlook", "", False, True)
'Add store to this session so all personal folder items can 
'be extracted to this store
'Here we specify source path for our pst file
objNsp.Session.AddStore(FullFilePath)

'Create MAPI Folder which represent Personal folder for outlook
Dim objFolder As Outlook.MAPIFolder = Nothing 

'Pick up Personal folder from this session of namespace object
objFolder = objNsp.Session.Folders.GetLast 

'Destination Path where PST will be extracted
dim strDestPath as String 'Process all items of this MAPI folder
ProcessFolder(objFolder,strDestPath)

The above code will create an Outlook object and get a namespace from that object in your application. This namespace will be of type MAPI. Note that you can process a PST file using a store to extract all Outlook items. Once we have a MAPIFolder available in our application, all we need to do is process this folder. Now let's see our ProcessFolder sub-routine:

Private Sub ProcessFolder(ByVal StartFolder As Outlook.MAPIFolder, _
    ByVal strPath As String)
'create directory for each of outlook item folder like 
'draft,inbox,deleted items and so on..
Directory.CreateDirectory(strPath)

    'process all the items in this folderDim i As Integer
    Dim objItem As Object
    For i = 1 To StartFolder.Items.Count
        objItem = StartFolder.Items.Item(i)
        'Save this item SaveItems(objItem, strPath)
        objItem = Nothing
    Next

    'process all the subfolders of this folder
    Dim objFolder As Outlook.MAPIFolder = Nothing
    For i = 1 To StartFolder.Folders.Count
        objFolder = StartFolder.Folders.Item(i)
        Dim strSubFolder As String
        strSubFolder = strPath & objFolder.Name
        Call ProcessFolder(objFolder, strSubFolder)
    Next
    objFolder = Nothing 
    objItem = Nothing 
End Sub 

You can see that the ProcessFolder() routine simply processes each sub-folder residing in our personal folder. If there are any items in any sub-folder, then we will save this item to our archive by calling the SaveItems() sub-routine. These items can be MailItems, Contacts, Notes, Tasks and so on. Our SaveItems() routine will look like this:

Private Sub SaveItems(ByVal objItem As Object, ByVal strFolderPath As String)
    Try 
        'Counter for messagesShared cnt As Int16 = 1 
        Dim MItem As Outlook.MailItem = Nothing 
        'Convert Object to MailItem Type
        MItem = CType(objItem, Outlook.MailItem) 

        If Not MItem Is Nothing Then
            'Save message in text files 
            Dim fs As FileStream = _
                File.Create(MsgPath + "\" + cnt.ToString & ".txt") 
            Dim st As New StreamWriter(fs) st.WriteLine(_
                "From : " & MItem.SenderName) 
            st.WriteLine("To : " & MItem.To) 
            st.WriteLine("CC : " & MItem.CC) 
            st.WriteLine("BCC : " & MItem.BCC) 
            st.WriteLine("Subject : " & MItem.Subject) 
            st.WriteLine() 
            st.WriteLine("Message Body :" & MItem.Body)
            st.AutoFlush = True 
            st.Close() 
            fs.Close() 
            'Finally Save Message File to extract attachments it contains
            strSaveName = (cnt.ToString) & ".msg" 
            'Save as message MItem.SaveAs(strFolderPath & "\" &(strSaveName))
            Dim tmpItem As Object 
            'Mail Attachment collection object 
            Dim tmpAttachs As Outlook.Attachments 
            'Single Attachment object 
            Dim tmpAttach As Outlook.Attachment 
            'Global Outlook Object
            dim mOulook as new Outlook.Application 
            'Create Template for this msg file 
            tmpItem = mOulook.CreateItemFromTemplate(_
                strFolderPath + "\" + strSaveName) 
            tmpAttachs = tmpItem.Attachments attchCount = tmpAttachs.Count
            For i = 1 To attchCount 
                tmpAttach = tmpAttachs.Item(i) 
                'Save attachment file 
                tmpAttach.SaveAsFile(strDestPath + "\" + tmpAttach.FileName)
            Next 
            cnt += 1 
        End If

This SaveItems() routine will save all messages to a text file and extract all attachments from it. Keep in mind that I have only processed MailItem, but you can check objects to any Outlook items such as tasks, calendars, contacts, meeting items and so on.

Points of Interest

I hope this article will be helpful to you while dealing with MS Outlook in your .NET applications. It's simple, as I've shown above, but we know that no lunch is free!!! With Outlook, it's the same. I mean that there are some points to keep in mind, like using sessions in namespace objects as I used. Even though we could have used the objNsp.AddStore() method, which is available in the namespace object itself, I have used a session in the namespace object to keep all PST extractions unique to that session. This helps you avoid exceptions like, "Outlook failed to add personal store to this session" to some extent. Otherwise, it's one of the most common exceptions you will face while programming Outlook-based applications.

Another point to remember is about implementing the IDisposable interface in your class. This interface provides the Dispose() method, which helps you free unmanaged resources like Outlook objects. Otherwise, these objects can leave resources locked that were used by them. Common examples of such resources are PST files, directories or any stream used in the application. So, it's advisable to release any COM objects used in the application, as they won't be automatically freed by Common Language Runtime (CLR).

Finally, It's worth mentioning one more thing: using this code, you cannot process any PST file that is password protected. Please use this code accordingly.

History

  • 11 October, 2007 -- Original version posted

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Tejas Patel
Web Developer
India India
Tejas has been an ASP.NET,AJAX/C#.NET/VB.NET developer for about 5 years for both windows and web application. Currently, he is working on Distributed Application as a team leader in his company.He has worked with languages like C,C++,Java,PHP and databases like MySQL,Oracle,SQL Server.He especially enjoy web development.He holds a MCTS certification in web application.
 
In his free time, he likes to listen music, and hang out with friends.

Comments and Discussions

 
QuestionUnable to cast COM object of type 'System.__ComObject' to interface type 'Oulook.MailItem' error Pinmembersigma_ivan14-Nov-11 17:11 
AnswerRe: Unable to cast COM object of type 'System.__ComObject' to interface type 'Oulook.MailItem' error PinmemberMember 960224628-Mar-13 3:49 
GeneralNeed to import my draft messages and inbox messages from outlook to my asp.net webforms PinmemberShubhMajumdar15-Nov-10 7:13 
GeneralMy vote of 5 PinmemberGurvinder singh21-Sep-10 0:09 
GeneralEmail Copying PinmemberPrateekPathak28-Jun-10 22:30 
Generalnot reading mails from pst Pinmemberanvnair11-Feb-10 21:44 
General[My vote of 1] delete this article... it is creating problem in company Pinmembertaruntest26-May-09 0:51 
GeneralOpen PST File with password procted Pinmemberkumar.goutam21-Jan-09 2:49 
GeneralConvert eml to pst [modified] PinmemberSwapnil96316-Dec-08 21:58 
GeneralRe: Convert eml to pst PinmemberTejas Patel17-Jan-09 20:42 
GeneralRe: Convert eml to pst PinmemberSwapnil Shah18-Jan-09 21:34 
QuestionHow get emails from Body of MailItem ?? Pinmemberalhambra-eidos21-Oct-08 10:52 
AnswerRe: How get emails from Body of MailItem ?? PinmemberTejas Patel23-Jan-09 7:30 
GeneralMy Similar software PinmemberAshutosh Bhawasinka3-Sep-08 9:06 
GeneralRe: My Similar software PinmemberTejas Patel17-Jan-09 20:26 
QuestionFile download link broken? PinmemberMember 43556631-Jul-08 20:28 
AnswerRe: File download link broken? PinmemberTejas Patel17-Jan-09 20:44 
Generalreading emails from other accounts PinmemberMikel A. Rodriguez18-Jun-08 22:56 
GeneralRe: reading emails from other accounts PinmemberAshutosh Bhawasinka27-Aug-08 18:12 
GeneralExtract emails from Thunderbird PinmemberGul Zakhmi27-Feb-08 20:25 
GeneralRe: Extract emails from Thunderbird PinmemberTejas Patel4-Jun-08 20:28 
GeneralExtract emails from Thunderbird Pinmemberdhams_developer4-Aug-08 2:51 
Generalthe same but for Outlook Express PinmemberNachoI13-Nov-07 3:11 
GeneralRe: the same but for Outlook Express PinmemberTejas G. Patel2-Jan-08 19:32 
Generalproblem with outlook xp+ warning dialog PinmemberUnruled Boy26-Oct-07 21:12 
GeneralRe: problem with outlook xp+ warning dialog PinmemberTejas G. Patel27-Oct-07 3:39 
GeneralRe: problem with outlook xp+ warning dialog Pinmemberrotabush15-Jan-10 21:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 11 Oct 2007
Article Copyright 2007 by Tejas Patel
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid