Eugene Astafiev

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!

26 Comments

  • https://secure.gravatar.com/avatar/b2808f676a96f6b3919f392eb5e1e212?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G WiglWagl says:

    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

  • https://secure.gravatar.com/avatar/bbd979ae5b772d0bc1f82065aa4ba146?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Eugene Astafiev says:

    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?

  • https://secure.gravatar.com/avatar/9360a4504e3cd5d1850f7a4fe7b23deb?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G David Aaron Ortiz says:

    Got this error: ‘Outlook.Items’ cannot be indexed because it has no default property

  • https://secure.gravatar.com/avatar/bbd979ae5b772d0bc1f82065aa4ba146?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Eugene Astafiev says:

    Hello David,

    What line of code fires the exception? Did you try to debug the code?

  • https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=32 Yagya says:

    what is marshal in the code?

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    System.Runtime.InteropServices.Marshal, see http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx.

  • https://secure.gravatar.com/avatar/6d42228da5c2261675ca417beae6b767?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Michele says:

    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]

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Michele,

    You need to call store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts). Please see http://msdn.microsoft.com/en-us/library/office/ff869924%28v=office.15%29.aspx.

  • https://secure.gravatar.com/avatar/25c3fe95dee9e3d360311f272481fe71?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G aniruddh bhatt says:

    Error:
    The Name ‘Marshal’ does not exist in the current context.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello aniruddh,

    Add
    using System.Runtime.InteropServices; // C#
    or
    Imports System.Runtime.InteropServices ‘ VB.NET

  • https://secure.gravatar.com/avatar/25c3fe95dee9e3d360311f272481fe71?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G aniruddh bhatt says:

    Yep It works, Thanks.

  • https://secure.gravatar.com/avatar/74c9eaae9fa189d9dc7b9998cc937085?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G dave says:

    is there a licence associated with this code.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Dave,

    Currently, no license is associated with this code.

  • https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=32 Mark says:

    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.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Mark,

    This type belongs to the Primary Outlook Interop, see http://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.

  • https://secure.gravatar.com/avatar/8fb8944541950b700c7ba86e5585e6b7?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Perry Garrod says:

    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

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    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 http://msdn.microsoft.com/en-us/library/office/ff865280%28v=office.15%29.aspx and http://msdn.microsoft.com/en-us/library/office/ff867889%28v=office.15%29.aspx.

  • https://secure.gravatar.com/avatar/c04401bc7c6aad7748d1bf8e376dc503?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Adam says:

    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.

  • https://secure.gravatar.com/avatar/c04401bc7c6aad7748d1bf8e376dc503?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Adam says:

    I’m also targeting .Net 4.0, rather than 4.5, if that has an effect.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    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 http://www.add-in-express.com/forum/read.php?FID=5&TID=12836.

  • https://secure.gravatar.com/avatar/c04401bc7c6aad7748d1bf8e376dc503?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Adam says:

    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? http://www.add-in-express.com/forum/read.php?FID=5&TID=12835

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    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.

  • https://secure.gravatar.com/avatar/030ea955e0b606381804c5924d17e993?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Mark says:

    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?

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    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.

  • https://secure.gravatar.com/avatar/49130753d2370abd3b0330fc81e38cae?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Ramandika says:

    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.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    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/2010/11/04/threads-managed-office-extensions/.

Post a comment

Have any questions? Ask us right now!