How To: Get a list of Outlook contacts
A while ago I described two ways of getting Outlook contact items from a folder: by using the Find/FindNext and Restrict methods of the Items class. Today I am going to show how you can get a list of all contacts of a certain Outlook user. As a rule, there are two folders containing contact items: Contacts and Suggested Contacts folders. You can get the Contacts folder using the GetDefaultFolder method of the Namespace class. The olFolderContacts constant of the OlDefaultFolders enumeration should be used for this task. But how can we get the Suggested Contacts folder?
Outlook 2010 introduced new constants in the OlDefaultFolders enumeration, which can be passed to the GetDefaultFolder method of the Namespace class. One of them is olFolderSuggestedContacts. As you may guess, it allows you to retrieve the Suggested Contacts folder in Outlook. This folder contains one-off entries that are used in pop-up prompts to finish the sentence when you enter an e-mail address in one of the recipient fields (TO, CC, BCC).
The code shown below collects all contact items from the two mentioned folders using the for loop. The function accepts an instance of the Application class from the Oultook Object Model and returns an instance of the generic List collection which contains contact items. Please remember that all underlying COM objects should be released later!
C# and Add-in Express:
using System.Collections.Generic; // ... private List<Outlook.ContactItem> GetListOfContacts(Outlook._Application OutlookApp) { List<Outlook.ContactItem> contactItemsList = null; Outlook.Items folderItems =null; Outlook.MAPIFolder folderSuggestedContacts = null; Outlook.NameSpace ns = null; Outlook.MAPIFolder folderContacts = null; object itemObj = null; try { contactItemsList = new List<Outlook.ContactItem>(); ns = OutlookApp.GetNamespace("MAPI"); // getting items from the Contacts folder in Outlook folderContacts = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts); folderItems = folderContacts.Items; for (int i = 1; folderItems.Count >= i; i++) { itemObj = folderItems[i]; if (itemObj is Outlook.ContactItem) contactItemsList.Add(itemObj as Outlook.ContactItem); else Marshal.ReleaseComObject(itemObj); } Marshal.ReleaseComObject(folderItems); folderItems = null; // getting items from the Suggested Contacts folder in Outlook folderSuggestedContacts = ns.GetDefaultFolder( Outlook.OlDefaultFolders.olFolderSuggestedContacts); folderItems = folderSuggestedContacts.Items; for (int i = 1; folderItems.Count >= i; i++) { itemObj = folderItems[i]; if (itemObj is Outlook.ContactItem) contactItemsList.Add(itemObj as Outlook.ContactItem); else Marshal.ReleaseComObject(itemObj); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } finally { if (folderItems != null) Marshal.ReleaseComObject(folderItems); if (folderContacts != null) Marshal.ReleaseComObject(folderContacts); if (folderSuggestedContacts != null) Marshal.ReleaseComObject(folderSuggestedContacts); if (ns != null) Marshal.ReleaseComObject(ns); } return contactItemsList; }
VB.NET and Add-in Express:
Imports System.Collections.Generic ' ... Private Function GetListOfContacts(OutlookApp As Outlook._Application) _ As List(Of Outlook.ContactItem) Dim contactItemsList As List(Of Outlook.ContactItem) = Nothing Dim folderItems As Outlook.Items = Nothing Dim folderSuggestedContacts As Outlook.MAPIFolder = Nothing Dim ns As Outlook.NameSpace = Nothing Dim folderContacts As Outlook.MAPIFolder = Nothing Dim itemObj As Object = Nothing Try contactItemsList = New List(Of Outlook.ContactItem)() ns = OutlookApp.GetNamespace("MAPI") ' getting items from the Contacts folder in Outlook folderContacts = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts) folderItems = folderContacts.Items For i As Integer = 1 To folderItems.Count itemObj = folderItems(i) If (TypeOf (itemObj) Is Outlook.ContactItem) Then contactItemsList.Add(itemObj) Else Marshal.ReleaseComObject(itemObj) End If Next Marshal.ReleaseComObject(folderItems) folderItems = Nothing ' getting items from the Suggested Contacts folder in Outlook folderSuggestedContacts = ns.GetDefaultFolder( _ Outlook.OlDefaultFolders.olFolderSuggestedContacts) folderItems = folderSuggestedContacts.Items For i As Integer = 1 To folderItems.Count itemObj = folderItems(i) If (TypeOf (itemObj) Is Outlook.ContactItem) Then contactItemsList.Add(itemObj) Else Marshal.ReleaseComObject(itemObj) End If Next Catch ex As Exception System.Windows.Forms.MessageBox.Show(ex.Message) Finally If Not IsNothing(folderItems) Then Marshal.ReleaseComObject(folderItems) End If If Not IsNothing(folderContacts) Then Marshal.ReleaseComObject(folderContacts) End If If Not IsNothing(folderSuggestedContacts) Then Marshal.ReleaseComObject(folderSuggestedContacts) End If If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns) End If End Try Return contactItemsList End Function
C# and VSTO:
using System.Runtime.InteropServices; // ... private List<Outlook.ContactItem> GetListOfContacts(Outlook._Application Application) { List<Outlook.ContactItem> contactItemsList = null; Outlook.Items folderItems = null; Outlook.MAPIFolder folderSuggestedContacts = null; Outlook.NameSpace ns = null; Outlook.MAPIFolder folderContacts = null; object itemObj = null; try { contactItemsList = new List<Outlook.ContactItem>(); ns = Application.GetNamespace("MAPI"); // getting items from the Contacts folder in Outlook folderContacts = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts); folderItems = folderContacts.Items; for (int i = 1; folderItems.Count >= i; i++) { itemObj = folderItems[i]; if (itemObj is Outlook.ContactItem) contactItemsList.Add(itemObj as Outlook.ContactItem); else Marshal.ReleaseComObject(itemObj); } Marshal.ReleaseComObject(folderItems); folderItems = null; // getting items from the Suggested Contacts folder in Outlook folderSuggestedContacts = ns.GetDefaultFolder( Outlook.OlDefaultFolders.olFolderSuggestedContacts); folderItems = folderSuggestedContacts.Items; for (int i = 1; folderItems.Count >= i; i++) { itemObj = folderItems[i]; if (itemObj is Outlook.ContactItem) contactItemsList.Add(itemObj as Outlook.ContactItem); else Marshal.ReleaseComObject(itemObj); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } finally { if (folderItems != null) Marshal.ReleaseComObject(folderItems); if (folderContacts != null) Marshal.ReleaseComObject(folderContacts); if (folderSuggestedContacts != null) Marshal.ReleaseComObject(folderSuggestedContacts); if (ns != null) Marshal.ReleaseComObject(ns); } return contactItemsList; }
VB.NET and VSTO:
Imports System.Runtime.InteropServices ' ... Private Function GetListOfContacts(OutlookApp As Outlook._Application) _ As List(Of Outlook.ContactItem) Dim contactItemsList As List(Of Outlook.ContactItem) = Nothing Dim folderItems As Outlook.Items = Nothing Dim folderSuggestedContacts As Outlook.MAPIFolder = Nothing Dim ns As Outlook.NameSpace = Nothing Dim folderContacts As Outlook.MAPIFolder = Nothing Dim itemObj As Object = Nothing Try contactItemsList = New List(Of Outlook.ContactItem)() ns = OutlookApp.GetNamespace("MAPI") ' getting items from the Contacts folder in Outlook folderContacts = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts) folderItems = folderContacts.Items For i As Integer = 1 To folderItems.Count itemObj = folderItems(i) If (TypeOf (itemObj) Is Outlook.ContactItem) Then contactItemsList.Add(itemObj) Else Marshal.ReleaseComObject(itemObj) End If Next Marshal.ReleaseComObject(folderItems) folderItems = Nothing ' getting items from the Suggested Contacts folder in Outlook folderSuggestedContacts = ns.GetDefaultFolder( _ Outlook.OlDefaultFolders.olFolderSuggestedContacts) folderItems = folderSuggestedContacts.Items For i As Integer = 1 To folderItems.Count itemObj = folderItems(i) If (TypeOf (itemObj) Is Outlook.ContactItem) Then contactItemsList.Add(itemObj) Else Marshal.ReleaseComObject(itemObj) End If Next Catch ex As Exception System.Windows.Forms.MessageBox.Show(ex.Message) Finally If Not IsNothing(folderItems) Then Marshal.ReleaseComObject(folderItems) End If If Not IsNothing(folderContacts) Then Marshal.ReleaseComObject(folderContacts) End If If Not IsNothing(folderSuggestedContacts) Then Marshal.ReleaseComObject(folderSuggestedContacts) End If If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns) End If End Try Return contactItemsList End Function
To get more information about the methods and properties provided by the Outlook Object Model, please use the Object Browser in the VBA environment.
See you on our forums and in the support e-mail address!
28 Comments
Hi,
thanks a lot, but i can’t get this running. Error in here:
private List GetListOfContacts(Outlook._Application OutlookApp)
Outlook is unknown. Is there missing an Assembly? In my code i use:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
using System.Globalization;
using Microsoft.Office.Interop.Outlook;
Thanks
Hi WiglWagl,
Please try to use an alias for the Outlook namespace in the following way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
using System.Globalization;
using Outlook = Microsoft.Office.Interop.Outlook;
Does this do the trick?
Got this error: ‘Outlook.Items’ cannot be indexed because it has no default property
Hello David,
What line of code fires the exception? Did you try to debug the code?
what is marshal in the code?
System.Runtime.InteropServices.Marshal, see https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx.
Hello to evrybody,
I find out this article by google and i hope someone can help me to solve a issue abaout outlook folders and store.
I work around a program to maanege contact for my customer, he has 4 differte PST file with 4 different contact folder (3 are normal PST 1 is a particular PST used in a contact share program).
If I use just
ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts)
I can’t see the contact in the other PST differt by default.
I findout a method to see all Archive attached to Outlook Session:
ns.stores (by a loop a can see ID and Displayed Name)
but there aren’t any way to access to it and get Contact folder.
Some one can help me to solve this issue?
My mail is [removed for security reasons]
Hello Michele,
You need to call store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts). Please see https://msdn.microsoft.com/en-us/library/office/ff869924%28v=office.15%29.aspx.
Error:
The Name ‘Marshal’ does not exist in the current context.
Hello aniruddh,
Add
using System.Runtime.InteropServices; // C#
or
Imports System.Runtime.InteropServices ‘ VB.NET
Yep It works, Thanks.
is there a licence associated with this code.
Hello Dave,
Currently, no license is associated with this code.
Hi,
I don’t know how _Application works: I need the contacts of the current user,
what _Application should I use?
Could you post the call to that methods?
Thank you.
Hello Mark,
This type belongs to the Primary Outlook Interop, see https://msdn.microsoft.com/EN-US/library/office/microsoft.office.interop.outlook._application%28v=office.15%29.aspx. You can try using _Application with Application. If there’s no compile-time problem, then it should work.
Hi Eugene
I need to review the Contact List for the current user (using VB.NET VSTO) so the code above looks good, but what I want from the Contact List is all the names and emails associated with specific Groups in the Contact List.
Is there an easy way to isolate just these “group lists”?
Thanks
Perry
Hello Perry,
I suppose you talk about distribution lists. If an item is a DistListItem, you retrieve individual members using DistListItem.MemberCount property and DistListItem.GetMember() method, see https://msdn.microsoft.com/en-us/library/office/ff865280%28v=office.15%29.aspx and https://msdn.microsoft.com/en-us/library/office/ff867889%28v=office.15%29.aspx.
I have two issues:
1. the olFolderSuggestedContacts constant isn’t available
2. If I pass in “(OlDefaultFolders )30”, I get an exception: {“The Suggested Contacts folder cannot be found.”}
I’m using VS2013 and currently developing against Outlook 2013.
My project is set to support outlook 2007 and greater. Though I could give up Outlook 2007 support.
I’m also targeting .Net 4.0, rather than 4.5, if that has an effect.
Hello Adam,
You don’t see it because that enumeration value was introduced in Outlook 2010. You can use late binding to get that folder; your “(OlDefaultFolders )30” is a correct way. Still, it will only work if your add-in is loaded in Outlook 2010+; yu need to check if ADXAddinModule.HostMajorVersion > 12. If you need to switch to supporting Outlook 2010+, please see https://www.add-in-express.com/forum/read.php?FID=5&TID=12836.
Hello Andrei,
I am currently debugging against Outlook 2013 and am getting that error.
(Loading version:15.0.0.4659 (15))
My ideal implementation would be to simply check to see if I were in Outlook 2010+ and if so, ask for suggested contacts.
Otherwise, only get the main contacts.
-Thanks
Adam
p.s. is it better to discuss here or over in the forums? https://www.add-in-express.com/forum/read.php?FID=5&TID=12835
Adam,
Sorry, your message has been in the pending category for quite a long time. The problem seems to be solved in those forum topics. If you have any other problem please let me know.
I know this is an older thread, but a quick question.
In the first example you are returning a Generic List of Outlook.ContactItem “List”
Does the caller that receives this list need to iterate through the list and release the com objects?
Hello Mark,
> Does the caller that receives this list need to iterate through the list and release the com objects?
Yes. All COM objects should be released. Just clearing the list won’t release the COM objects. You need to walk through the list and release every ContactItem; when this is done, you can clear the list.
As I’ve read we can’t use COM object in the secondary thread, though we can but many people say it’s not safe and can crash the outlook. So if that’s the case where to run this GetListOfContacts method ? Basically I would like to do the same thing but to get all inbox emails from all accounts.
Hello Ramandika,
You need to run such a method on the main thread. Since scanning folders may take a lot of time, I suggest that you do this in chinks, say, 3-200 emails per chunk. You will need to introduce a delay between chunks. This delay will allow user activity.
You may want to check “On using threads in managed Office extensions” at https://www.add-in-express.com/creating-addins-blog/threads-managed-office-extensions/.
I have copied the above function for C# and VSTO .. how do I call this function ?
i need to get list of all outlook contacts and need to select the contact and import in a text field .
Hello Sean,
Simply, create an add-in project showing a Ribbon button in Outlook. In the Click event of the button, invoke this function. Sorry, the blog implies one knows the essentials, therefore we do not cover such things in detail.