'Fast searching an Outlook Address list

I want to search an huge address list from outlook for an AddressEntry by the email address. Searching by name is not problem, as you can write:

Microsoft.Office.Interop.Outlook.AddressEntry = AddressEntries[Name];

But I want to find the Entry by its email. This code is working but extremely slow:

    public static string GetUserDataByEmailAddress(string EmailAddress)
    {
        Microsoft.Office.Interop.Outlook.Application OLApp = null;
        bool OutlookWasRunning = false;
        string UserName = string.Empty;

        if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
        {
            OLApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application;
            OutlookWasRunning = true;
        }
        else
        {
            OLApp = new Microsoft.Office.Interop.Outlook.Application();
            Microsoft.Office.Interop.Outlook.NameSpace nameSpace = OLApp.GetNamespace("MAPI");
            nameSpace.Logon("", "", System.Reflection.Missing.Value, System.Reflection.Missing.Value);
            nameSpace = null;
            OutlookWasRunning = false;
        }

        Microsoft.Office.Interop.Outlook.AddressLists GALs = null;
        GALs = OLApp.Session.AddressLists;
        if (GALs == null) { throw new System.Exception("ERROR: Unable to get address book collection from MS Outlook!"); }

        Microsoft.Office.Interop.Outlook.AddressList gal = null;
        gal = GALs["Globale Adressliste"];
        if (gal == null) { throw new System.Exception("ERROR: Unable to get address book 'Global Address List' from MS Outlook!"); }

        foreach (Microsoft.Office.Interop.Outlook.AddressEntry ent in gal.AddressEntries)
        {
            if(ent.Address == EmailAddress) { UserName = ent.Name; }
        }

        if (!OutlookWasRunning) { OLApp.Quit(); }

        return UserName;
    }

Ok, but this way works very slow. Now, I tried to use the AddressEntries as an IEnumeratable to do this:

var output = from a in gal.AddressEntries.AsQueryable() where (a as Microsoft.Office.Interop.Outlook.AddressEntry).Address == EmailAddress select a;

Doing that, I get the error:

Severity Code Description Project File Line Suppression State Error CS1936 Could not find an implementation of the query pattern for source type 'IQueryable'. 'Where' not found.

Does anybody know an fast way to search for the correct AddressEntry?

Regards, Jan



Solution 1:[1]

Do not loop through all items in a container - some containers can contain tens of thousands of entries or more.

You can use Namespace.CreateRecipient / Recipient.Resolve in OOM - that will resolve a name (or address) against all containers. This is equivalent to typing a name in the To edit box in Outlook and hitting Ctrl+K.

If you want to resolve against a particular container (e.g. "All Users" GAL container), you would need to use Extended MAPI (C++ or Delphi only). You can use Redemption (I am its author - any language) - it exposes RDOSession.AddressBook.ResolveName / ResolveNameEx and RDOAddresList.ResolveName / ResolveNameEx .

Keep in mind that resolving against a particular container (PR_ANR resolution in MAPI) might not work if using an SMTP address (GAL limitation).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1