Pieter van der Westhuizen

How to get unread mail in Outlook: C# code examples

Finding and filtering items in Outlook can be done in a variety of ways and in this article we’ll focus on ways to retrieve unread mail from Outlook.

The following C# code examples demonstrate different techniques of getting unread mail items in Outlook.

Creating an Outlook add-in

To get started with our project we’ll create an Outlook add-in using Add-in Express for Office and .net, and then add a new ADXRibbon to the AddinModule designer surface.

Adding a new ribbon tab to the AddinModule designer surface

Next, add four Ribbon buttons and three Ribbon Label controls to the ADXRibbon and change the design to be similar to the following image:

The design of the Find Unread Mail tab

Get the number of unread emails using the UnreadItemCount property

The Outlook Folder item has a property called UnReadItemCount. This property returns a long value indicating the number of unread items in the Outlook folder. This property is the fastest way to just get the number of unread emails in Outlook.

In order to use the method, create a new event handler for the “Use UnReadItemCount property” and add the following code to it:

private void adxRibbonButtonUnreadItems_OnClick(object sender,
    IRibbonControl control, bool pressed)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder currFolder = null;
 
    try
    {
        currExplorer = OutlookApp.ActiveExplorer();
        currFolder = currExplorer.CurrentFolder as Outlook.Folder;
        MessageBox.Show(
            "Number of unread items in current folder is " +
            currFolder.UnReadItemCount);
    }
    finally
    {
        if (currFolder != null) Marshal.ReleaseComObject(currFolder);
        if (currExplorer != null) Marshal.ReleaseComObject(currExplorer);
    }
}

Getting the collection of unread mails using the Restrict() method

The Restrict method can be found on the Outlook Items object and is considerably faster than the Find and FindNext method when working with a large number of mail items in the Outlook folder. This method returns a new collection of items based on the specified filter. To test this method, add a new event handler for the “Use Restrict() method” button and add the following code to it:

private void adxRibbonButtonUseRestrict_OnClick(object sender,
    IRibbonControl control, bool pressed)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder currFolder = null;
    Outlook.Items folderItems = null;
    Outlook.Items restrictedItems = null;
    Outlook.MailItem mail = null;
    Outlook.Attachments attachments = null;
    int attachmentCount = 0;
    Stopwatch stopWatch = null;
 
    try
    {
        stopWatch = new Stopwatch();
        stopWatch.Start();
        currExplorer = OutlookApp.ActiveExplorer();
        currFolder = currExplorer.CurrentFolder as Outlook.Folder;
        if (currFolder.DefaultItemType == Outlook.OlItemType.olMailItem)
        {
            folderItems = currFolder.Items;
            restrictedItems = folderItems.Restrict("[Unread]=true");
            adxRibbonLabelUnreadCount.Caption =
                string.Format("Total number of unread e-mails in {0} is {1}",
                currFolder.Name, restrictedItems.Count.ToString());
 
            for (int i = 1; i <= restrictedItems.Count; i++)
            {
                mail = restrictedItems[i] as Outlook.MailItem;
                if (mail != null)
                {
                    attachments = mail.Attachments;
                    attachmentCount += attachments.Count;
                    Marshal.ReleaseComObject(attachments);
                    Marshal.ReleaseComObject(mail);
                }
            }
            adxRibbonLabelAttachmentCount.Caption =
               string.Format("Total number of attachments in unread e-mails are {0}",
               attachmentCount);
        }
        stopWatch.Stop();
        adxRibbonLabelTimeElapsed.Caption =
           "Elapsed Time: " + stopWatch.Elapsed.Milliseconds + " milliseconds";
    }
    finally
    {
        if (restrictedItems != null) Marshal.ReleaseComObject(restrictedItems);
        if (folderItems != null) Marshal.ReleaseComObject(folderItems);
        if (currFolder != null) Marshal.ReleaseComObject(currFolder);
        if (currExplorer != null) Marshal.ReleaseComObject(currExplorer);
    }
}

In the code above we obtained a reference to the current Outlook folder and by using the Restrict method, we specified that it should filter the folder items and only return the unread messages. We then looped through the returned items and counted each unread mail's attachments.

Iterate through unread emails using Find() and FindNext()

The Find and FindNext methods of the Outlook Items object are faster than the Restrict method, but only when working with a small number of items. The Find method returns a single item based on the filter, but if you want to retrieve the next mail item that matches the filter you would have to call the FindNext method.

In the following code, we'll use the Find method to find all unread mail items in the folder. Note how instead of using a 'for' loop we use a 'while' loop in conjunction with the FindNext() method.

private void adxRibbonButtonUseFind_OnClick(object sender,
    IRibbonControl control, bool pressed)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder currFolder = null;
    Outlook.Items folderItems = null;
    Outlook.MailItem foundMail = null;
    Outlook.Attachments attachments = null;
    object foundItem = null;
    int attachmentCount = 0;
    int unreadCount = 0;
    Stopwatch stopWatch = null;
 
    try
    {
        stopWatch = new Stopwatch();
        stopWatch.Start();
        currExplorer = OutlookApp.ActiveExplorer();
        currFolder = currExplorer.CurrentFolder as Outlook.Folder;
        if (currFolder.DefaultItemType == Outlook.OlItemType.olMailItem)
        {
            folderItems = currFolder.Items;
            foundItem = folderItems.Find("[Unread]=true");
            while (foundItem != null)
            {
                if (foundItem is Outlook.MailItem)
                {
                    foundMail = foundItem as Outlook.MailItem;
                    attachments = foundMail.Attachments;
                    attachmentCount += attachments.Count;
                    unreadCount++;
                    Marshal.ReleaseComObject(attachments);
                }
                if (foundItem != null) Marshal.ReleaseComObject(foundItem);
 
                foundItem = folderItems.FindNext();
            }
        }
        adxRibbonLabelUnreadCount.Caption =
           string.Format("Total number of unread e-mails in {0} is {1}",
           currFolder.Name, unreadCount);
        adxRibbonLabelAttachmentCount.Caption =
            string.Format("Total number of attachments in unread e-mails are {0}",
            attachmentCount);
        stopWatch.Stop();
        adxRibbonLabelTimeElapsed.Caption =
            "Elapsed Time: " + stopWatch.Elapsed.Milliseconds + " milliseconds";
    }
    finally
    {
        if (folderItems != null) Marshal.ReleaseComObject(folderItems);
        if (currFolder != null) Marshal.ReleaseComObject(currFolder);
        if (currExplorer != null) Marshal.ReleaseComObject(currExplorer);
    }
}

Loop through unread mails returned by the Folder.GetTable() method

The GetTable method can be found on the Outlook Folder object and returns a Table object. The Table object was added to Outlook 2007 to improve performance with the Items collection. Each item returned inside the Table object only contains a certain number of fields, which means you would need to load the items returned using the GetItemFromID method.

In the following code, we'll retrieve a new Table object and using a While loop, it would loop through all the returned items and load each item using the GetItemFromId mehod:

private void adxRibbonButtonUseFolderGetTable_OnClick(object sender,
    IRibbonControl control, bool pressed)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder currFolder = null;
    Outlook.Table foundItemsTable = null;
    Outlook.NameSpace session = null;
    int unreadCount = 0;
    int attachmentCount = 0;
    Stopwatch stopWatch = null;
 
    try
    {
        stopWatch = new Stopwatch();
        stopWatch.Start();
        currExplorer = OutlookApp.ActiveExplorer();
        currFolder = currExplorer.CurrentFolder as Outlook.Folder;
        session = OutlookApp.Session;
        if (currFolder.DefaultItemType == Outlook.OlItemType.olMailItem)
        {
            foundItemsTable = currFolder.GetTable("[Unread]=true");
            unreadCount = foundItemsTable.GetRowCount();
            adxRibbonLabelUnreadCount.Caption =
                string.Format("Total number of unread e-mails in {0} is {1}",
                currFolder.Name, unreadCount);
            while (!foundItemsTable.EndOfTable)
            {
                Outlook.Row row = foundItemsTable.GetNextRow();
                Outlook.MailItem mail =
                    session.GetItemFromID(row["EntryId"].ToString()) as Outlook.MailItem;
                if (mail != null)
                {
                    Outlook.Attachments attachments = mail.Attachments;
                    attachmentCount += attachments.Count;
                    Marshal.ReleaseComObject(mail);
                    Marshal.ReleaseComObject(attachments);
                }
                Marshal.ReleaseComObject(row);
            }
            adxRibbonLabelAttachmentCount.Caption =
                string.Format("Total number of attachments in unread e-mails are {0}",
                attachmentCount);
        }
        stopWatch.Stop();
        adxRibbonLabelTimeElapsed.Caption =
            "Elapsed Time: " + stopWatch.Elapsed.Milliseconds + " milliseconds";
    }
    finally
    {
        if (session != null) Marshal.ReleaseComObject(session);
        if (foundItemsTable != null) Marshal.ReleaseComObject(foundItemsTable);
        if (currFolder != null) Marshal.ReleaseComObject(currFolder);
        if (currExplorer != null) Marshal.ReleaseComObject(currExplorer);
    }
}

Getting unread mail in Outlook - performance tests

You'll notice that in the code examples above, we used the Stopwatch class in order to determine the amount of time it takes to retrieve and loop through all the unread mail items in Outlook.

Method Unread items in folder Total attachments Total items in folder Execution Time (milliseconds)
Find/FindNext 20 8 7216 26
Restrict 20 8 7216 20
GetTable 20 8 7216 25

Thank you for reading. Until next time, keep coding!

Available downloads:

This sample Outlook add-in was developed using Add-in Express for Office and .net:

Outlook Unread Mail sample add-in (C#)

6 Comments

  • pregunton says:

    How can convert OST to PST ? or extract EMLs from OST file? using C# thx

  • Andrei Smolin (Add-in Express Team) says:

    Hello pregunton,

    The Outlook object model doesn’t provide such a way. I don’t think there’s a way to covert an OST to a PST. As to extracting EML files, I suggest that you google for a solution.

  • machau says:

    I want to use the above mentioned apis to retrieve Outlook Items but I want to use something similar to limit. For example Collection of Unread Mail from last N mails. Please guide

  • Andrei Smolin (Add-in Express Team) says:

    Hello machau,

    Get a list of items using Folder.Items or Folder.GetTable; see Items at https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/items-object-outlook; Table – https://msdn.microsoft.com/VBA/Outlook-VBA/articles/table-object-outlook.

    Filter the list using Items.Restrict() or Table.Restrict(). Sort the list by date (new to older) using Items.Sort() or Table.Sort(). Get N first items.

  • TAYYABA says:

    i want to extract the .xls file from the folder in the inbox in outlook using c# desktop application plz help me

    thamks in advance

  • Anonymous says:

    Hello TAYYABA,

    You start with getting the current selection using Explorer.Selection – note that this call may fire an exception when in certain folders such as RSS Feeds. Then you make sure the selection isn’t null and check if the selection contains any items: see Selection.Count. After that you get the selected item(s): object item = Selection[i]; i changes from 1 to Selection.Count. Cast *item*: Outlook._MailItem mail = item as Outlook._MailItem. If mail is null, you release *item* and selection, and return. If mail is okay, check if mail.Attachments contains an attachment that you need, and save it via Attachment.SaveAsFile().

    Find properties and methods above described at https://docs.microsoft.com/en-us/office/vba/api/overview/outlook.

Post a comment

Have any questions? Ask us right now!