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.
- Get the number of unread emails
- Get the collection of unread mails
- Iterate through unread emails
- Loop through unread mails returned by Folder.GetTable()
- Performance tests
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.
Next, add four Ribbon buttons and three Ribbon Label controls to the ADXRibbon and change the design to be similar to the following image:
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:
6 Comments
How can convert OST to PST ? or extract EMLs from OST file? using C# thx
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.
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
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.
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
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.