Getting started with Outlook Converter


Introduction

While the rest of the world uses the open standard called MIME for storing e-mail messages, MS Office Outlook uses its own set of proprietary formats to store e-mails. Outlook uses .MSG files to store individual e-mails and .PST files to represent the whole database of e-mail accounts, folders, and items in these folders (which may include e-mail messages, contacts, events, and so on).

MailBee.NET Outlook Converter provides MsgConvert and PstReader classes which allow your application to convert individual e-mails between .MSG and MIME formats or read any data from .PST files or streams. Items extracted from .PST container are automatically converted into MIME format.

For instance, you can create an e-mail using MailMessage class or take an existing e-mail, then convert it into .MSG format and open it with Outlook. You can also programmatically import the produced .MSG file into Outlook application using its own API.

Or, you can take an .MSG file or particular item from a .PST file, convert it into MIME, and then save it as .EML file, modify it with MailMessage methods and properties, send it as outgoing e-mail, or convert the modified e-mail back to .MSG format.

Outlook Converter does NOT require MS Outlook to be installed and does not depend on any third-party components, it's 100% managed .NET code.


More facts on Outlook and its file formats

This topic provides some facts which are not required to learn how to use Outlook Converter but may help you better understand Outlook in general.

Outlook and Outlook Express

Outlook (MS Office Outlook) and Outlook Express (OE) are DIFFERENT things. Although their names may look similar, these programs have very little in common. For instance, Outlook does not support MIME format (.EML files) but does support .MSG and .PST formats. At the same time, OE does support .EML but does not support .MSG and .PST formats. Outlook Converter is all about MS Office Outlook.

Outlook and MIME format

Although Outlook does not support files in MIME format, it can still parse and produce MIME-formatted messages when receiving or sending e-mail. This is because messages between e-mail servers are exchanged using MIME format only. Still, for unknown reason, Outlook does not provide any means to work with MIME format besides e-mail network protocols.

Well, it turns out newer versions of Outlook can open .EML files under some conditions but still can't save them. Anyway, .EML is still not the best message format for Outlook.

.MSG and .PST formats

.MSG and .PST formats are binary while MIME is text (.EML are normal text files). You cannot edit or adjust .MSG or .PST in any text editor like you can do with .EML file.

.MSG files can be in Outlook 97-2002 format (32-bit file) and in Outlook 2003+ format (64-bit file). Both are supported with Outlook Converter. Also, Outlook 2007 introduces the support of .MSGX format which is XML-based. It's not supported by Outlook Converter but you can use any XML parsing/building tool to read or write it. And Outlook 2007 and newer versions still fully support classic .MSG and .PST formats.

Note that some e-mail programs use .MSG extension for files which are actually in MIME format (i.e. .MSG extension does not yet guarantee you have a file in Outlook .MSG format). Most programs, however, use the correct, non-ambiguous extension for MIME messages which is .EML. With Outlook Converter, you can use any extensions for any file formats.

International characters, Unicode and ANSI formats

.MSG files can be 8-bit ANSI and 16-bit Unicode. if you deal with e-mails containing international characters, Unicode format is preferred. By default, MailBee.NET produces Unicode .MSG files during .EML to .MSG conversions.

HTML and RTF body

.MSG (.PST) and MIME formats are not just containers of the same data. For instance, .MSG and .PST usually use RTF to represent rich-formatted body while MIME format uses HTML for that.

Outlook Converter can extract RTF from .MSG and attach it to the resulting MIME but no e-mail program except of Outlook will be able to read it. For instance, Outlook Express cannot deal with RTF. You can, however, load this RTF into RichTextBox component or other tool capable of rendering RTF.

However, .MSG files usually have HTML version in addition to RTF. Although Outlook does not primarily use that HTML version to display e-mail and uses RTF for that, it usually puts the HTML version into produced messages. This way, a typical e-mail generated by Outlook has 3 bodies: plain-text, HTML, and RTF.

Another case is when you need to convert MIME e-mail with HTML body  into .MSG file. For that, HTML must be converted into RTF. Outlook Converter provides basic means of such conversion (which can be suitable in most cases), and lets you use any external converter for high-quality HTML-to-RTF conversion. Although Outlook can display .MSG files which have HTML body and no RTF body, the problem occurs when you try to forward or reply such e-mail. For this to succeed, the original message must have RTF body as well.


Feature List

The below is what you can do with Outlook Converter component:

You can also use this component together with other components of MailBee.NET family (for instance, receive an e-mail with POP3 and convert it into .MSG format, or extract an .PST item and send it via SMTP).


Import namespaces and set license key

In NuGet Package Manager console, run:

Install-Package MailBee.NET

If NuGet is not an option, see similar topic in MailBee.NET SMTP or MailBee.NET IMAP/POP3 guides on how to add a reference to MailBee.NET assembly by other means.

Now, import the required namespaces at the top of your code file:

using MailBee;
using MailBee.Mime;
using MailBee.Outlook
Imports MailBee
Imports MailBee.Mime
Imports MailBee.Outlook

Note that MailBee and MailBee.Mime namespaces do not directly belong to Outlook Converter but the classes in these namespaces are commonly used with Outlook Converter classes.

After importing namespaces, unlock the component with your trial or permanent license key. The key can be specified in the code, in app.config/web.config, in the registry.

Depending on whether you're using MsgConvert or PstReader class (or both), you'll need to specify your license key for the class being used or for both. The license key is the same for both MsgConvert or PstReader classes because they both are part of the same component and share the same license.

Option A - specify license key directly in code

Before the first use and creating any instances of MsgConvert or PstReader classes, set the static MailBee.Global.LicenseKey property to assign the license key (if you haven't done this before). It's assumed you've already imported MailBee.Outlook namespace with using (C#) or Imports (VB) directives.

MailBee.Global.LicenseKey = "MN100-0123456789ABCDEF-0123";
MailBee.Global.LicenseKey = "MN100-0123456789ABCDEF-0123"

You can also create and unlock instances of MsgConvert or PstReader classes, passing the license key as a parameter of MsgConvert(string) or PstReader(string) constructor. Again, it's assumed you've already imported MailBee.Outlook namespace.

PstReader pstRead = newPstReader(@"C:\Temp\outlook.pst", "MN100-0123456789ABCDEF-0123");
MsgConvert msgConv = newMsgConvert("MN100-0123456789ABCDEF-0123");
Dim pstRead As New PstReader("C:\Temp\outlook.pst""MN100-0123456789ABCDEF-0123")
Dim msgConv As New MsgConvert("MN100-0123456789ABCDEF-0123")

Option B - put license key in app.config or web.config

Alternatively, in app.config or web.config locate <appSettings> entry in <configuration> section (if it's not there, create it), and add MailBee.NET license key as follows:

<?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <appSettings>
      <add key="MailBee.Global.LicenseKey" value="MN100-0123456789ABCDEF-0123"/>
  </appSettings>
</configuration>

Note that <appSettings> may also appear as <applicationSettings> in your case.

If <appSettings> originally looked as <appSettings/> (self-closing tag syntax), you'll need to unfold it to <appSettings></appSettings> so that you could insert <add key .../> there.

If you do not yet have app.config or web.config, see Import namespaces and set license key in MailBee.NET SMTP guide on how to add it.


Convert .MSG file to .EML

It's easy to convert Outlook .MSG file into MIME format:

MsgConvert conv = new MsgConvert();
conv.MsgToEml(@"C:\Temp\test.msg"@"C:\Temp\test.eml");
Dim conv As MsgConvert = New MsgConvert
conv.MsgToEml("C:\Temp\test.msg""C:\Temp\test.eml")

This code assumes MailBee.Outlook namespace is already imported and the license key is set.

You can also use streams instead of filenames if you need to.


Convert .EML file to .MSG

It's easy too:

MsgConvert conv = new MsgConvert();
conv.EmlToMsg(@"C:\Temp\test.eml"@"C:\Temp\test.msg");
Dim conv As MsgConvert = New MsgConvert
conv.EmlToMsg("C:\Temp\test.eml""C:\Temp\test.msg")

This method also allows you to use streams instead of filenames.


Parse .MSG file and access the parsed e-mail data

MsgConvert.MsgToMailMessage method allows you to get .MSG file or data stream as MailMessage object. You can read or alter its properties, call methods, send this with Smtp class, convert it back to .MSG, serialize to XML, save it as .EML file, or do whatever else.

The code snippet below reads an .MSG file and displays its subject, plain-text body (and HTML body if available) and saves all attachments into a folder.

MsgConvert conv = new MsgConvert();
MailMessage msg = conv.MsgToMailMessage("C:\\Temp\\test.msg");
Console.WriteLine("Subject: " + msg.Subject);
Console.WriteLine("Plain-text body follows:");
Console.WriteLine();
Console.WriteLine(msg.BodyPlainText);
Console.WriteLine("----------------------------------------");
if (msg.BodyHtmlText != string.Empty)
{
    Console.WriteLine("HTML body follows:");
    Console.WriteLine();
    Console.WriteLine(msg.BodyHtmlText);
    Console.WriteLine("----------------------------------------");
}
msg.Attachments.SaveAll("C:\\Temp");
Console.WriteLine("Attachments:");
foreach (Attachment attach in msg.Attachments)
{
    Console.WriteLine(attach.Filename);
}
Dim conv As New MsgConvert()
Dim msg As MailMessage = conv.MsgToMailMessage("C:\Temp\test.msg")
Console.WriteLine("Subject: " + msg.Subject)
Console.WriteLine("Plain-text body follows:")
Console.WriteLine()
Console.WriteLine(msg.BodyPlainText)
Console.WriteLine("----------------------------------------")
If msg.BodyHtmlText <> String.Empty Then
    Console.WriteLine("HTML body follows:")
    Console.WriteLine()
    Console.WriteLine(msg.BodyHtmlText)
    Console.WriteLine("----------------------------------------")
End If
msg.Attachments.SaveAll("C:\Temp")
Console.WriteLine("Attachments:")
For Each attach As Attachment In msg.Attachments
    Console.WriteLine(attach.Filename)
Next

This sample does not deal with RTF (Rich-text) body. See MsgConvert.RtfInEmlMethod property documentation on how to get and display RTF body.


Create .MSG file from scratch

This code snippet below creates a new e-mail with plain-text and HTML parts containing some international text, adds a couple of attachments, and makes an .MSG file from it. Outlook Converter automatically creates RTF version of HMTL data.

// Create new MIME message.
MailMessage msg = new MailMessage();

// Set headers.
msg.From.Email = "jdoe@domain.com";
msg.From.DisplayName = "John Doe";
msg.To.Add("Sarah", "sdoe@company.com");
msg.Subject = "Hello (English),Привет (Russian),안녕하세요 (Korean)";

// Create plain-text body with international content.
msg.BodyPlainText = "Message text in English\r\n" +
    "Текст сообщения на русском\r\n" +
    "한국어의 텍스트 메시지";

// Create HTML body with international content.
msg.BodyHtmlText = "<html><b>Message text in English</b><br/>" +
    "<b>Текст сообщения на русском</b><br/>" +
    "<b>한국어의 텍스트 메시지</b></html>";

// Add two attachments in different ways.
msg.Attachments.Add("C:\\Temp\\report.doc");
msg.Attachments.Add("C:\\Temp\\12345678.tmp", "data.xls");

// Initialize Outlook Converter.
MsgConvert conv = new MsgConvert();

// We need Unicode as the message contains international chars.
conv.MsgAsUnicode = true;

// Tell MailBee.NET to create RTF from HTML.
conv.HtmlToRtfMethod = HtmlToRtfConversionMethod.Internal;

// The message is not intended to be editable.
conv.MsgAsDraft = false;

// Create .MSG file.
conv.MailMessageToMsg(msg, "C:\\Temp\\result.msg");
' Create new MIME message.
Dim msg As New MailMessage()

' Set headers.
msg.From.Email = "jdoe@domain.com"
msg.From.DisplayName = "John Doe"
msg.To.Add("Sarah", "sdoe@company.com")
msg.Subject = "Hello (English),Привет (Russian),안녕하세요 (Korean)"

' Create plain-text body with international content.
msg.BodyPlainText = "Message text in English" & vbCrLf & _
    "Текст сообщения на русском" & vbCrLf & "한국어의 텍스트 메시지"

' Create HTML body with international content.
msg.BodyHtmlText = "<html><b>Message text in English</b><br/>" & _
    "<b>Текст сообщения на русском</b><br/>" & _
    "<b>한국어의 텍스트 메시지</b></html>"

' Add two attachments in different ways.
msg.Attachments.Add("C:\Temp\report.doc")
msg.Attachments.Add("C:\Temp\12345678.tmp", "data.xls")

' Initialize Outlook Converter.
Dim conv As New MsgConvert()

' We need Unicode as the message contains international chars.
conv.MsgAsUnicode = True

' Tell MailBee.NET to create RTF from HTML.
conv.HtmlToRtfMethod = HtmlToRtfConversionMethod.Internal

' The message is not intended to be editable.
conv.MsgAsDraft = False

' Create .MSG file.
conv.MailMessageToMsg(msg, "C:\Temp\result.msg")

Create .MSG file from IMAP e-mail

You can convert any MailMessage object no matter how you got it (from an e-mail server, XML, stream, etc). The code snippet below gets the last e-mail from an IMAP inbox and converts it into an editable .MSG draft:

// Get e-mail via IMAP.
MailMessage msg = Imap.QuickDownloadMessage("mail.domain.com", "jdoe", "secret", "Inbox", -1);

// You can adjust the message if you need to.

// Initialize Outlook Converter.
MsgConvert conv = new MsgConvert();

// The message is intended to be editable.
conv.MsgAsDraft = true;

// Create .MSG file.
conv.MailMessageToMsg(msg, "C:\\Temp\\result.msg");
' Get e-mail via IMAP.
Dim msg As MailMessage = Imap.QuickDownloadMessage("mail.domain.com", "jdoe", "secret", "Inbox", -1)

' You can adjust the message if you need to.

' Initialize Outlook Converter.
Dim conv As New MsgConvert()

' The message is intended to be editable.
conv.MsgAsDraft = True

' Create .MSG file.
conv.MailMessageToMsg(msg, "C:\Temp\result.msg")

As this sample also uses Imap class, you'll need to import MailBee.ImapMail namespace and make sure your license key covers IMAP component.


Export .MSG file into Outlook

You can easily load .MSG file you got from MailBee.NET into Outlook. The console sample below is the extended version of the previous code snippet, it loads the produced .MSG file into Outlook inbox. Unlike previous samples, this sample requires Outlook to be installed on the computer.

using System;
using MailBee;
using MailBee.Mime;
using MailBee.Outlook;
using MailBee.ImapMail;
using Microsoft.Office.Interop.Outlook;

class Sample
{
    static void Main(string[] args)
    {
        // Get e-mail via IMAP.
        MailMessage msg = Imap.QuickDownloadMessage(
            "mail.domain.com", "jdoe", "secret", "Inbox", -1);

        // You can adjust the message if you need to.

        // Initialize Outlook Converter.
        MsgConvert conv = new MsgConvert();

        // The message is intended to be editable.
        conv.MsgAsDraft = true;

        // Create .MSG file.
        conv.MailMessageToMsg(msg, "C:\\Temp\\result.msg");

        // Get Outlook's inbox.
        Microsoft.Office.Interop.Outlook.Application outlookApp = new Application();
        Microsoft.Office.Interop.Outlook.NameSpace ns = outlookApp.GetNamespace("MAPI");
        Microsoft.Office.Interop.Outlook.MAPIFolder outlookInbox = ns.GetDefaultFolder(
            Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

        // Load .MSG file into Oulook inbox.
        Microsoft.Office.Interop.Outlook.MailItem inboxItem = null;
        inboxItem = outlookApp.Application.CreateItemFromTemplate("C:\\Temp\\result.msg");
        inboxItem.Move(outlookInbox);
    }
}
Imports MailBee
Imports MailBee.Mime
Imports MailBee.Outlook
Imports MailBee.ImapMail
Imports Microsoft.Office.Interop.Outlook

Module Module1
    Sub Main()
        ' Get e-mail via IMAP.
        Dim msg As MailMessage = Imap.QuickDownloadMessage( _
        "mail.domain.com", "jdoe", "secret", "Inbox", -1)

        ' You can adjust the message if you need to.

        ' Initialize Outlook Converter.
        Dim conv As New MsgConvert()

        ' The message is intended to be editable.
        conv.MsgAsDraft = True

        ' Create .MSG file.
        conv.MailMessageToMsg(msg, "C:\Temp\result.msg")

        ' Get Outlook's inbox.
        Dim outlookApp As Microsoft.Office.Interop.Outlook.Application = New Application()
        Dim ns As Microsoft.Office.Interop.Outlook.NameSpace = outlookApp.GetNamespace("MAPI")
        Dim outlookInbox As Microsoft.Office.Interop.Outlook.MAPIFolder = _
            ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox)

        ' Load .MSG file into Oulook inbox.
        Dim inboxItem As Microsoft.Office.Interop.Outlook.MailItem = Nothing
        inboxItem = outlookApp.Application.CreateItemFromTemplate("C:\Temp\result.msg")
        inboxItem.Move(outlookInbox)
    End Sub
End Module

For this sample to work, you'll also need to add a reference to Microsoft.Office.Interop.Outlook in Add Reference dialog.


Get MailMessage from Outlook inbox and save it as .EML file

Although you can also extract data from Outlook's .PST file directly (see next topics), you may get e-mails and other items from Outlook via its API. Of course, this assumes that Outlook is installed on the computer where the application is running.

The console sample below saves the last e-mail in Outlook inbox as .MSG file. Then, the sample reads this file and converts it into MailMessage object and saves as .EML file.

using System;
using MailBee;
using MailBee.Mime;
using MailBee.Outlook;
using Microsoft.Office.Interop.Outlook;

class Sample
{
    static void Main(string[] args)
    {
        // Get Outlook's inbox.
        Microsoft.Office.Interop.Outlook.Application outlookApp = new Application();
        Microsoft.Office.Interop.Outlook.NameSpace ns = outlookApp.GetNamespace("MAPI");
        Microsoft.Office.Interop.Outlook.MAPIFolder outlookInbox = ns.GetDefaultFolder(
            Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

        if (outlookInbox.Items.Count > 0)
        {
            // Note that Outlook's message indices are 1-based, not zero-based.
            // Also, this line may cause Outlook to display security warning.
            Microsoft.Office.Interop.Outlook.MailItem outlookMsg =
                outlookInbox.Items[outlookInbox.Items.Count];

            Console.WriteLine("Subject as in Outlook: " + outlookMsg.Subject);

            // Save e-mail as .MSG
            outlookMsg.SaveAs("C:\\Temp\\email.msg");

            // Initialize Outlook Converter.
            MsgConvert conv = new MsgConvert();

            // If the message has RTF body, let's attach it to the converted e-mail.
            conv.RtfInEmlMethod = RtfInEmlStorageMethod.AsAttachment;

            // Convert .MSG file to .EML MIME format.
            conv.MsgToEml("C:\\Temp\\email.msg", "C:\\Temp\\result.eml");

            // Or, load the .MSG, convert to .EML in memory, and display its properties
            MailMessage msg = conv.MsgToMailMessage("C:\\Temp\\email.msg");

            // If the convesion is OK, subject should be the same value as in Outlook.
            Console.WriteLine("Subject of converted e-mail: " + msg.Subject);
        }
        else
        {
            Console.WriteLine("Outlook inbox was empty");
        }
    }
}
Imports MailBee
Imports MailBee.Mime
Imports MailBee.Outlook
Imports Microsoft.Office.Interop.Outlook

Module Module1
    Sub Main()
        ' Get Outlook's inbox.
        Dim outlookApp As Microsoft.Office.Interop.Outlook.Application = New Application()
        Dim ns As Microsoft.Office.Interop.Outlook.NameSpace = outlookApp.GetNamespace("MAPI")
        Dim outlookInbox As Microsoft.Office.Interop.Outlook.MAPIFolder = _
            ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox)

        If outlookInbox.Items.Count > 0 Then
            ' Note that Outlook's message indices are 1-based, not zero-based.
            ' Also, this line may cause Outlook to display security warning.
            Dim outlookMsg As Microsoft.Office.Interop.Outlook.MailItem = _
                outlookInbox.Items(outlookInbox.Items.Count)

            Console.WriteLine("Subject as in Outlook: " + outlookMsg.Subject)

            ' Save e-mail as .MSG
            outlookMsg.SaveAs("C:\Temp\email.msg")

            ' Initialize Outlook Converter.
            Dim conv As New MsgConvert()

            ' If the message has RTF body, let's attach it to the converted e-mail.
            conv.RtfInEmlMethod = RtfInEmlStorageMethod.AsAttachment

            ' Convert .MSG file to .EML MIME format.
            conv.MsgToEml("C:\Temp\email.msg", "C:\Temp\result.eml")

            ' Or, load the .MSG, convert to .EML in memory, and display its properties
            Dim msg As MailMessage = conv.MsgToMailMessage("C:\Temp\email.msg")

            ' If the convesion is OK, subject should be the same value as in Outlook.
            Console.WriteLine("Subject of converted e-mail: " + msg.Subject)
        Else
            Console.WriteLine("Outlook inbox was empty")
        End If
    End Sub
End Module

The sample assumes MailBee.Global.LicenseKey is set in the app.config/web.config file or registry. You'll also need to add a reference to Microsoft.Office.Interop.Outlook in Add Reference dialog.

Note that Outlook may display a warning when another application tries to access its resources.


Read .PST file without Outlook

This console sample displays From field of all the e-mails in Inbox, and saves the last e-mails in Inbox and Drafts as .EML files:

using System;
using MailBee;
using MailBee.Mime;
using MailBee.Outlook;

class Sample
{
    static void Main(string[] args)
    {
        // If Outlook is installed and running, the .PST file may be blocked for read access.
        PstReader pstRead = new PstReader(@"C:\Temp\Outlook.pst");
        PstFolderCollection folders = pstRead.GetPstRootFolders(true);
        foreach (PstFolder folder in folders)
        {
            if (folder.ShortName.ToLower() == "inbox")
            {
                // For all inbox e-mails, display subject.
                MailMessage inboxMsg = null;
                foreach (PstItem item in folder.Items)
                {
                    inboxMsg = item.GetAsMailMessage();
                    Console.WriteLine(inboxMsg.Subject);
                }

                // And save the last e-mail to disk as .EML file.
                if (inboxMsg != null)
                {
                    inboxMsg.SaveMessage(@"C:\Temp\inbox.eml");
                }
            }

            // Save last e-mail in Drafts folder to disk as .EML file.
            // Here, we do not use "foreach" and access the last item directly.
            if (folder.ShortName.ToLower() == "drafts")
            {
                if (folder.Items.Count > 0)
                {
                    // Note that indices are zero-based (in Outlook interop, they are 1-based).
                    MailMessage draftsMsg = folder.Items[folder.Items.Count - 1].GetAsMailMessage();
                    draftsMsg.SaveMessage(@"C:\Temp\drafts.eml");
                }
            }
        }

        pstRead.Close();
    }
}
Imports MailBee
Imports MailBee.Mime
Imports MailBee.Outlook

Module Module1
    Sub Main()
        ' If Outlook is installed and running, the .PST file may be blocked for read access.
        Dim pstRead As New PstReader("C:\Temp\Outlook.pst")
        Dim folders As PstFolderCollection = pstRead.GetPstRootFolders(True)
        For Each folder As PstFolder In folders
            If folder.ShortName.ToLower() = "inbox" Then
                ' For all inbox e-mails, display subject.
                Dim inboxMsg As MailMessage = Nothing
                For Each item As PstItem In folder.Items
                    inboxMsg = item.GetAsMailMessage()
                    Console.WriteLine(inboxMsg.Subject)
                Next

                ' And save the last e-mail to disk as .EML file.
                If inboxMsg IsNot Nothing Then
                    inboxMsg.SaveMessage("C:\Temp\inbox.eml")
                End If
            End If

            ' Save last e-mail in Drafts folder to disk as .EML file.
            ' Here, we do not use "For Each" and access the last item directly.
            If folder.ShortName.ToLower() = "drafts" Then
                If folder.Items.Count > 0 Then
                    ' Note that indices are zero-based (in Outlook interop, they are 1-based).
                    Dim draftsMsg As MailMessage = _
                        folder.Items(folder.Items.Count - 1).GetAsMailMessage()
                    draftsMsg.SaveMessage("C:\Temp\drafts.eml")
                End If
            End If
        Next

        pstRead.Close()
    End Sub
End Module

The sample assumes MailBee.Global.LicenseKey is set in the app.config/web.config file or registry.

Outlook, however, is not required, and there are no its interop dependencies.


Read contacts, appointments, and other items from .PST file

MailBee.NET can extract items of any type from a .PST file. This includes not only e-mail messages but also contacts, activities, tasks, rss items, appointments, and any other items which can be stored in a .PST file.

You can can access the specific properties of an .PST item with PstFields property (hash table of values) available for every item extracted.

Also, you can use GetAsMailMessage method to convert the extracted item into MIME format (this lets you work with non-emails like if they were e-mails, using the same methods, e.g. serialize them to .XML, save to file, etc). For such items, MailBee.NET will add all the specific property values as X-... headers to their MIME source.

For instance, PstRss.GetAsMailMessage method adds X-Rss-<property_name> headers while PstContact.GetAsMailMessage method adds X-Contact-<property_name> ones.

PstFields property documentation on every .PST item type lists all the the available specific properties and their types (e.g. PstRss.PstFieldsPstContact.PstFields, etc).

The code snippet below displays some details on all the contacts found in Contacts folder of the .PST file:

// If Outlook is installed and running, the .PST file may be blocked for read access.
PstReader pstRead = new PstReader(@"C:\Temp\Outlook.pst");
PstFolderCollection folders = pstRead.GetPstRootFolders(true);
foreach (PstFolder folder in folders)
{
    if (folder.ShortName.ToLower() == "contacts")
    {
        foreach (PstItem item in folder.Items)
        {
            PstContact contact = item as PstContact;

            if (contact != null)
            {
                Console.WriteLine(string.Format(
                    "Given name = {0}, surname = {1}, Email1 = {2}",
                    contact.PstFields["GivenName"], contact.PstFields["Surname"],
                    contact.PstFields["Email1EmailAddress"]));
            }
        }
    }
}

pstRead.Close();
' If Outlook is installed and running, the .PST file may be blocked for read access.
Dim pstRead As New PstReader("C:\Temp\Outlook.pst")
Dim folders As PstFolderCollection = pstRead.GetPstRootFolders(True)
For Each folder As PstFolder In folders
    If folder.ShortName.ToLower() = "contacts" Then
        For Each item As PstItem In folder.Items
            Dim contact As PstContact = TryCast(item, PstContact)

            If contact IsNot Nothing Then
                Console.WriteLine(String.Format( _
                    "Given name = {0}, surname = {1}, Email1 = {2}", _
                    contact.PstFields("GivenName"), contact.PstFields("Surname"), _
                    contact.PstFields("Email1EmailAddress")))
            End If
        Next
    End If
Next

pstRead.Close()

This sample does not need Outlook to be installed on the computer. However, if Outlook is installed and running, may need to close it to let other applications access its .PST file.

This code snippet assumes MailBee.Global.LicenseKey is set in the app.config/web.config file or registry, and MailBee.Outlook namespace is imported.


.MSG, .PST and .EML streams

All the samples in this guide use .MSG, .EML and .PST as files but you may want to know that all the methods used in the sample also have overloads accepting Stream instead of filename. Thus, you can work with .PST and .MSG data in memory, not saving anything to the filesystem.

The above, however, only corresponds to Outlook Converter itself. If you're using Outlook interop, you have to use files because Outlook does not provide any Stream-based methods to exchange e-mail data between applications.


Advanced topics and fine-tuning

This article briefly highlights some specific matters of Outlook Converter.

PstReader does support S/MIME signed e-mails. Upon extraction, you can use Smime class to verify the extracted MailMessage. You'll need MailBee.NET Security license for that (included in MailBee.NET Objects unified key).

On MSG-EML conversion, you can use MsgConvert.RtfInEmlMethod property to control whether and how to include RTF body into the resulting MIME message. If extracting data from .PST file, the property name is PstMessage.RtfInEmlMethod.

MsgConvert.OnByteToStringConversion delegate is handy if you convert international e-mails from non-Unicode .MSG to .EML. You can supply your own version of converting .MSG data from bytes to string (which will, for instance, use non-default Encoding for that). This may help if you know the codepage of the source .MSG message (if it's not Unicode, MailBee.NET assumes the default codepage because .MSG file does not provide the information which codepage it uses).

MsgConvert.MsgAsUnicode propery sets if the resulting .MSG file of EML-to-MSG conversion should be Unicode. Set it to false if you need ANSI for some reason.

MsgConvert.MsgAsDraft let's you control whether the user will be able to edit the resulting .MSG file prior to sending, or it can only be sent without alteration.

PstReader class provides PstReader.GetFolderByID and PstReader.GetItemByID methods which let you access arbitrary items of a .PST file without iterating through all the items. These methods usually are not needed if you process the file only once (e.g. convert its contents to .EML files) but can be useful if you work with this .PST file in more complex ways.


Send feedback to AfterLogic

Copyright © 2006-2023 AfterLogic Corporation. All rights reserved.