Outlook Email Extractor






4.39/5 (17 votes)
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 MailItem
s, Contact
s, Note
s, Task
s 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