Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / Visual Basic
Article

Outlook Email Extractor

Rate me:
Please Sign up or sign in to vote.
4.39/5 (19 votes)
11 Oct 2007Ms-PL4 min read 171.3K   5.7K   96   29
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:

VB
'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:

VB
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:

VB
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)


Written By
Web Developer
Canada Canada
Tejas has been an ASP.NET,AJAX/C#.NET/VB.NET developer for about 10 years for windows, WCF, RESTful services, windows and web application. Currently, he is working on Distributed Applications as a team lead in his company. He has worked with languages like C,C++,Java,PHP and databases like MS SQL Server, Oracle and MySQL. He especially enjoy web development using service driven architectures. He holds a MCSD certification since July 2013.

In his free time, he likes to learn new technologies including real world business processes, contribute to online forums/blogs, listen to music and hang out with friends.

Comments and Discussions

 
QuestionUnable to cast COM object of type 'System.__ComObject' to interface type 'Oulook.MailItem' error Pin
sigma_ivan14-Nov-11 16:11
sigma_ivan14-Nov-11 16:11 
AnswerRe: Unable to cast COM object of type 'System.__ComObject' to interface type 'Oulook.MailItem' error Pin
Member 960224628-Mar-13 2:49
Member 960224628-Mar-13 2:49 
GeneralNeed to import my draft messages and inbox messages from outlook to my asp.net webforms Pin
ShubhMajumdar15-Nov-10 6:13
ShubhMajumdar15-Nov-10 6:13 
GeneralMy vote of 5 Pin
Gurvinder singh20-Sep-10 23:09
Gurvinder singh20-Sep-10 23:09 
GeneralEmail Copying Pin
PrateekPathak28-Jun-10 21:30
PrateekPathak28-Jun-10 21:30 
Generalnot reading mails from pst Pin
anvnair11-Feb-10 20:44
anvnair11-Feb-10 20:44 
General[My vote of 1] delete this article... it is creating problem in company Pin
taruntest25-May-09 23:51
taruntest25-May-09 23:51 
GeneralOpen PST File with password procted Pin
kumar.goutam21-Jan-09 1:49
kumar.goutam21-Jan-09 1:49 
GeneralConvert eml to pst [modified] Pin
Swapnil Shah16-Dec-08 20:58
Swapnil Shah16-Dec-08 20:58 
GeneralRe: Convert eml to pst Pin
Tejas Patel17-Jan-09 19:42
Tejas Patel17-Jan-09 19:42 
GeneralRe: Convert eml to pst Pin
Swapnil Shah18-Jan-09 20:34
Swapnil Shah18-Jan-09 20:34 
QuestionHow get emails from Body of MailItem ?? Pin
kiquenet.com21-Oct-08 9:52
professionalkiquenet.com21-Oct-08 9:52 
AnswerRe: How get emails from Body of MailItem ?? Pin
Tejas Patel23-Jan-09 6:30
Tejas Patel23-Jan-09 6:30 
GeneralMy Similar software Pin
Ashutosh Bhawasinka3-Sep-08 8:06
Ashutosh Bhawasinka3-Sep-08 8:06 
GeneralRe: My Similar software Pin
Tejas Patel17-Jan-09 19:26
Tejas Patel17-Jan-09 19:26 
Questionaccessing the webserver to retreive mails. Pin
anandghodake12-Aug-08 21:14
anandghodake12-Aug-08 21:14 
AnswerRe: accessing the webserver to retreive mails. Pin
Tejas Patel17-Jan-09 19:29
Tejas Patel17-Jan-09 19:29 
QuestionFile download link broken? Pin
Steve @ Industrial1-Jul-08 19:28
Steve @ Industrial1-Jul-08 19:28 
AnswerRe: File download link broken? Pin
Tejas Patel17-Jan-09 19:44
Tejas Patel17-Jan-09 19:44 
Generalreading emails from other accounts Pin
Mikel A. Rodriguez18-Jun-08 21:56
Mikel A. Rodriguez18-Jun-08 21:56 
Hello!
I have some questions about this article. I have written a similar program to yours for reading unread and inbox emails. I would like to know if it's possible to connect to another email account in the same network without writing a password. Is there any credentialcache as when you send an email? Can I get the list of all the existing emails of users that are in the same local area network?
Thanks in advance
GeneralRe: reading emails from other accounts Pin
Ashutosh Bhawasinka27-Aug-08 17:12
Ashutosh Bhawasinka27-Aug-08 17:12 
GeneralExtract emails from Thunderbird Pin
Gul Mohammad27-Feb-08 19:25
Gul Mohammad27-Feb-08 19:25 
GeneralRe: Extract emails from Thunderbird Pin
Tejas Patel4-Jun-08 19:28
Tejas Patel4-Jun-08 19:28 
GeneralExtract emails from Thunderbird Pin
dhams_developer4-Aug-08 1:51
dhams_developer4-Aug-08 1:51 
Generalthe same but for Outlook Express Pin
NachoI13-Nov-07 2:11
NachoI13-Nov-07 2:11 

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

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