Search code examples
c#outlookcontactssubdirectory

How do I find the contents of a specific Outlook Contacts subfolder?


I need to extract the contacts (Employees) listed in a specified (by name) subfolder in Outlook Contacts. I've been at it for days, and tried every scrap of code I can find on the internet, but to no avail. I have seen suggestions about how it could be done, but none of them actually work.

Here's my running code. You can drop it in a console app in Visual Studio as-is. I can find the contents of my "Contacts" folder, and I can find the list of folders, but can't work out how to get the contents of a sub folder.

We're using Outlook 365.

using System;
using System.Collections.Generic;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace OutlookTest
{
    public class OutlookDataRetriever
    {
        public static int Main(string[] args)
        {
            try
            {
                Outlook.Application oApp = new Outlook.Application();


                Console.WriteLine("\n\nShow Contacts folders:");
                Outlook.MAPIFolder folderContacts = oApp.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderContacts);
                foreach (Outlook.MAPIFolder subfolder in folderContacts.Folders)
                {
                    Console.WriteLine("folder::: " + subfolder.Name + " ::: " + subfolder.FolderPath);
                }

                Console.WriteLine("\n\nShow members of Contacts folder:");
                Outlook.MAPIFolder fldContacts = (Outlook.MAPIFolder)oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
                Outlook.Items contactsFolder = fldContacts.Items;
                foreach (var contact in contactsFolder)
                {
                    if (contact is Outlook.ContactItem)
                    {
                        Outlook.ContactItem thisContact = (Outlook.ContactItem)contact;
                        Console.WriteLine("contact::: " + thisContact.FullName + " ::: " + thisContact.Email1DisplayName);
                    }
                    else
                    {
                        Console.WriteLine("I'm guessing this is a folder, but can't figure out how to cast it to access its contents.");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception caught.", e);
            }
            return 0;
        }
    }
}

My References: snapshot of the solution explorer showing references

Here's the output I get:

Show Contacts folders:
folder::: {06967759-274D-40B2-A3EB-D7F9E73727D7} ::: \\KNye@myOrganization.com\Contacts\{06967759-274D-40B2-A3EB-D7F9E73727D7}
folder::: {A9E2BC46-B3A0-4243-B315-60D991004455} ::: \\KNye@myOrganization.com\Contacts\{A9E2BC46-B3A0-4243-B315-60D991004455}
folder::: Companies ::: \\KNye@myOrganization.com\Contacts\Companies
folder::: GAL Contacts ::: \\KNye@myOrganization.com\Contacts\GAL Contacts
folder::: Kristy Nye[1] ::: \\KNye@myOrganization.com\Contacts\Kristy Nye[1]
folder::: Kristy Nye ::: \\KNye@myOrganization.com\Contacts\Kristy Nye
folder::: Recipient Cache ::: \\KNye@myOrganization.com\Contacts\Recipient Cache
folder::: PeopleCentricConversation Buddies ::: \\KNye@myOrganization.com\Contacts\PeopleCentricConversation Buddies
folder::: Kristy's Addresses ::: \\KNye@myOrganization.com\Contacts\Kristy's Addresses
folder::: Organizational Contacts ::: \\KNye@myOrganization.com\Contacts\Organizational Contacts


Show members of Contacts folder:
contact::: Matt Smith ::: Matt Smith (ESmith@myOrganization.com)
contact::: Kristy J Nye ::: Kristy J Nye (KNye@myOrganization.com)
I'm guessing this is a folder, but can't figure out how to cast it to access its contents.

Here's a screenshot of my Contacts folder: Screenshot of Contacts folder

Here's the contents of my folder, "ThisIsATestGroup":Contents of "ThisIsATestGroup" folder

My objective: I want to query "Find all contacts in "ThisIsATestGroup", and get back:

  • Edgar B
  • Kristy J N
  • Rey G M
  • Richard D N

How do I get the contacts in this specific subfolder only??? Thank you!


Solution

  • After much pulling of hair and gnashing of teeth, I found my own answer. Here 'tis:

    using System;
    using Outlook = Microsoft.Office.Interop.Outlook;
    
    namespace OutlookTest
    {
        public class OutlookDataRetriever
        {
            public static int Main(string[] args)
            {
                string myFolder = "ThisIsATestGroup";
                try
                {
                    Console.WriteLine("Show members of '" + myFolder + "' list:");
    
                    Outlook.Application oApp = new Outlook.Application();
    
                    /* Get a list of items in the contactsfolder  */
                    Outlook.MAPIFolder fldContacts = (Outlook.MAPIFolder)oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
                    Outlook.Items contactsFolder = fldContacts.Items;
    
                    /* Find the contacts folder with the name I'm looking for.  MS documentation calls this a DistListItem.  Baffled me for a long time because their UI calls it a contact group. */
                    string filter = "[Subject] = '" + myFolder + "'";
                    var targetFolder = contactsFolder.Find(filter);
                    Outlook.DistListItem myDistList = (Outlook.DistListItem)targetFolder;
                    Console.WriteLine("myDistList::: " + myDistList.Subject);
    
                    /* List all the members in my list */
                    for (int i = 1; i <= myDistList.MemberCount; i++) // Index starts at 1, not 0 !!!
                    {
                        var aMember = myDistList.GetMember(i);
                        Console.WriteLine("      member::: " + i.ToString() + " " + aMember.Name + " ::: " + aMember.Address);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("{0} Exception caught.", e);
                }
                return 0;
            }
        }
    }
    

    On my way to the above solution, I found another solution which has the added benefit of allowing you to look through everything in your contacts folder. Both solutions return the correct result, but I suspect the top one runs faster.

    namespace OutlookTest
    {
        public class OutlookDataRetriever
        {
            public static int Main(string[] args)
            {
                try
                {
                    Outlook.Application oApp = new Outlook.Application();
    
                    Console.WriteLine("Show members of 'ThisIsATestGroup' list:");
                    Outlook.MAPIFolder fldContactsX = (Outlook.MAPIFolder)oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
                    Outlook.Items contactsFolder = fldContactsX.Items;
                    foreach (var contact in contactsFolder)
                    {
                        if (contact is Outlook.ContactItem)
                        {
                            Outlook.ContactItem thisContact = (Outlook.ContactItem)contact;
                            Console.WriteLine("contact::: " + thisContact.FullName + " ::: " + thisContact.Email1DisplayName);
                        }
                        else
                        {
                            if (contact is Outlook.DistListItem)
                            {
                                Outlook.DistListItem thisDistList = (Outlook.DistListItem)contact;
                                Console.WriteLine("distList::: " + thisDistList.Subject);
    
                                if (thisDistList.Subject == "ThisIsATestGroup")
                                {
    
                                    for (int i = 0; i < thisDistList.MemberCount; i++)
                                    {
                                        var aMember = thisDistList.GetMember(i + 1);
                                        Console.WriteLine("      member::: " + i.ToString() + " " + aMember.Name + " ::: " + aMember.Address);
                                    }
                                }
                            }
                            else
                            {
                                Console.WriteLine("Should never reach this line.");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("{0} Exception caught.", e);
                }
                return 0;
            }
        }
    }
    

    Enjoy!