Question

Trying my luck here after hour of searching.

Let's say you have Outlook 2010 with two active accounts: john.doe@company.com, admin.test@company.com.

You need to pull Global Address List for admin.test@company.com:

            using Microsoft.Office.Interop.Outlook;

            Application app = new Application();
            NameSpace ns = app.GetNamespace("MAPI");
            ns.Logon("", "", false, true);

            AddressList GAL = ns.AddressLists["Global Address List"];

            foreach (AddressEntry oEntry in GAL.AddressEntries)
            {
                // do something
            }

The problem here is that GAL can belong to either account and it's not obvious, at least by reading MSDN, how you suppose to specify which account you really want to use.

If we will go through all lists like that:

foreach (AddressList lst in ns.AddressLists)
{
    Console.WriteLine("{0}, {1}", lst.Name, lst.Index);
}

We can see that there is two entries named "Global Address List", two entries named "Contacts", etc with different indexes, but it's still not clear which one belongs to which account.

For folders it's done quite nicely since you can use constructs like that:

ns.Folders["admin.test@company.com"].Folders["Inbox"];

but I can't figure out similar mechanism for AddressLists.

Any help appreciated.

Thank you.

Was it helpful?

Solution 2

I used Account.CurrentUser UID and matched AddressList UID to select the correct list. I don't know if using Store is a better approach, but this one works nicely.

Richard and Dmitry thank you for help.

Also Dmitry I want to thank you for maintaining the only source of all MAPI tags available on the Internet.

Code:

using Microsoft.Office.Interop.Outlook;

const string PR_EMSMDB_SECTION_UID = "http://schemas.microsoft.com/mapi/proptag/0x3D150102";

Application app = new Application();
NameSpace ns = app.GetNamespace("MAPI");
ns.Logon("", "", false, true);

string accountName = "admin.test@company.com";
string accountUID = null;

// Get UID for specified account name
foreach (Account acc in ns.Accounts)
{
    if (String.Compare(acc.DisplayName, accountName, true) == 0)
    {
        PropertyAccessor oPAUser = acc.CurrentUser.PropertyAccessor;
        accountUID = oPAUser.BinaryToString(oPAUser.GetProperty(PR_EMSMDB_SECTION_UID));
        break;
    }
}

// Select GAL with matched UID
foreach (AddressList GAL in ns.AddressLists)
{
    if (GAL.Name == "Global Address List")
    {
        PropertyAccessor oPAAddrList = GAL.PropertyAccessor;
        if (accountUID == oPAAddrList.BinaryToString(oPAAddrList.GetProperty(PR_EMSMDB_SECTION_UID)))
        {
            foreach (AddressEntry oEntry in GAL.AddressEntries)
            {
                // do something
            }
            break;
        }
    }
}

OTHER TIPS

GALs from different servers need to be correlated with the corresponding stores and accounts using the profile (IProfAdmin) and account management API (IOlkAccountManager). These interfaces are only accessible in C++ or Delphi. You will need to read PR_EMSMDB_SECTION_UID from both stores (IMsgSTore) and address book objects (IABContainer). If you need to match it against an account, that same value will be available in the PROP_MAPI_EMSMDB_SECTION_UID (0x20070102) property in the IOlkAccount object - you can see it in OutlookSpy if you click IOlkAccountManager button and double click on an Exchange account.

If using Redemption is an option, you can use the RDOExchangeAccount object, which exposes GAL, AllAddressLists, PrimaryStore, PublicFolders, etc. properties.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top