Read Outlook PST File and Get Folders and SubFolders Information

Aspose.Email for .NET provides an API for reading Microsoft Outlook PST files. You can load a PST file from disk or stream into an instance of the PersonalStorage class and get the information about its contents, for example, folders, subfolders, and messages. The API also provides the capability to include search folders while traversing for messages from the PST folders.

Loading a PST File

An Outlook PST file can be loaded in an instance of the PersonalStorage class. The following code snippet shows you how to load the PST file.

Displaying Folders Information

After loading the PST file in the PersonalStorage class, you can get the information about the file display name, root folder, subfolders and messages count. The following code snippet shows you how to display the name of PST file, folders and the number of messages in the folders.

Get user-defined folders only

PST/OST files may contain folders which were created by a user. Aspose.Email provides the ability to access only user-defined folders by using the PersonalStorageQueryBuilder.OnlyFoldersCreatedByUser property. You can set the PersonalStorageQueryBuilder.OnlyFoldersCreatedByUser property to true to get only user-defined folders. The following code snippet demonstrates the use of PersonalStorageQueryBuilder.OnlyFoldersCreatedByUser to get user-defined folders.

Checking whether the folder is in a predefined folder

When opening and inspecting the folders within a PST (Personal Storage Table) file, you can check whether each folder is a predefined folder type or a subfolder of a predefined folder type, and obtain the information about each folder.

The FolderInfo.GetPredefinedType(bool getForTopLevelParent) method allows to check whether a folder is from StandardIpmFolder. If getForTopLevelParent param is true, method returns a StandardIpmFolder enum value for the top-level parent folder. This determines whether the current folder is a subfolder of a predefined folder. If getForTopLevelParent param is false, it returns a StandardIpmFolder enum value for the current folder.

The following code sample shows how to implement this feature into your project:

PersonalStorage.FromFile("my.pst"))
        {
            FolderInfoCollection folders = pst.RootFolder.GetSubFolders();

            foreach (FolderInfo folder in folders)
            {
                Console.WriteLine($"Folder: {folder.DisplayName}");
                Console.WriteLine($"Is predefined: {folder.GetPredefinedType(false) != StandardIpmFolder.Unspecified}");
                Console.WriteLine("-----------------------------------");
            }
        }
    }

Getting and adding a standard RSS Feeds folder in PersonalStorage

Aspose.Email makes it possible to retrieve a reference to the predefined folder that holds RSS feeds. This could be useful if you want to programmatically access and manipulate the RSS feeds stored in an Outlook PST file. Give the value of RssFeeds to the StandardIpmFolder enum.

The following code example shows how to get an RSS Feeds folder.

using (var pst = PersonalStorage.FromFile("my.pst", false))
{
    var rssFolder = pst.GetPredefinedFolder(StandardIpmFolder.RssFeeds);
}

To add an RSS Feeds folder, use the following code snippet:

using (var pst = PersonalStorage.Create("my.pst", FileFormatVersion.Unicode))
{
    var rssFolder = pst.CreatePredefinedFolder("RSS Feeds", StandardIpmFolder.RssFeeds);
}

Parsing Searchable Folders

A PST/OST may contain searchable folders in addition to the normal type of folders. Aspose.Email provides the FolderKind enumerator for specifying the messages from such search folders with EnumerateFolders and GetSubFolders methods. The following code snippet shows you how to parse searchable folders.

using (PersonalStorage pst = PersonalStorage.FromFile("my.pst"))
        {
            FolderInfoCollection folders = pst.RootFolder.GetSubFolders(FolderKind.Search | FolderKind.Normal);

            // Browse through each folder to display folder name and number of messages
            foreach (FolderInfo folder in folders)
            {
                Console.WriteLine($"Folder: {folder.DisplayName}");

                FolderInfoCollection subFolders = folder.GetSubFolders(FolderKind.Search | FolderKind.Normal);
                foreach (FolderInfo subFolder in subFolders)
                {
                    Console.WriteLine($"Sub-folder: {subFolder.DisplayName}");
                }
            }
        }

Retrieving Parent Folder Information from MessageInfo

The following code snippet shows you how to retrieve parent folder information from MessageInfo.

Retrieve a PST subfolder by path

The FolderInfo.GetSubFolder(string name, bool ignoreCase, bool handlePathSeparator) method overload will enable you to retrieve a subfolder with the specified name from the current PST folder.

The method takes the following parameters:

  • name - specifies the name of the subfolder to retrieve.
  • ignoreCase - determines whether the search for the subfolder name should be case-sensitive or case-insensitive. If set to true, the search will be case-insensitive, otherwise, it will be case-sensitive.
  • handlePathSeparator - specifies whether the specified folder name should be treated as a path if it contains backslashes. If set to true, the method will interpret the folder name as a path, attempting to navigate to the subfolder using the path. If set to false, the method will treat the folder name as a simple name, searching for a subfolder with an exact name match.

The following code sample demonstrates how to implement this method in your project:

var folder = pst.RootFolder.GetSubFolder(@"Inbox\Reports\Jan", true, true);
In this sample, the method will return a Jan named folder that is located at the Inbox\Reports\ path relative to the root folder.

PST file traversal API

The traversal API allows extracting all PST items as far as possible, without throwing out exceptions, even if some data of the original file is corrupted. The following steps show how to use this API.

Use PersonalStorage constructor and Load method instead of FromFile method.

The constructor allows defining a callback method.

using (var currentPst = new PersonalStorage((exception, itemId) => { /* Exception handling  code. */ }))

Loading and traversal exceptions will be available through the callback method.

The Load method returns ‘true’ if the file has been loaded successfully and further traversal is possible. If a file is corrupted and no traversal is possible, ‘false’ is returned.

if (currentPst.Load(inputStream))

This allows to open and traverse even corrupted PST files without throwing out exceptions. And exceptions and corrupted items will be handled by the callback method.

using (PersonalStorage pst = new PersonalStorage((exception, itemId) => { /* Exception handling  code. */ }))
{
    if (pst.Load(@"test.pst"))
	{
		GetAllMessages(pst, pst.RootFolder);
	}
}

private static void GetAllMessages(PersonalStorage pst, FolderInfo folder)
{
    foreach (var messageEntryId in folder.EnumerateMessagesEntryId())
    {
        MapiMessage message = pst.ExtractMessage(messageEntryId);
    }
    foreach (var subFolder in folder.GetSubFolders())
    {
        GetAllMessages(pst, subFolder);
    }
}