访问多个Outlook帐户的全局地址列表

时间:2013-03-12 19:39:17

标签: c# outlook office-interop mapi

在搜索一小时后试试我的运气。

让我们假设您拥有两个活动帐户的Outlook 2010:john.doe @ company.com,admin.test @ company.com。

您需要提取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
            }

这里的问题是GAL可以属于任何一个帐户,并且它不是很明显,至少通过阅读MSDN,你如何指定你真正想要使用哪个帐户。

如果我们将查看所有列表:

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

我们可以看到有两个名为"全局地址列表"的条目,两个名为" Contacts"等具有不同索引的条目,但它仍然不清楚哪个一个属于哪个帐户。

对于文件夹,它可以很好地完成,因为你可以使用这样的结构:

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

但我无法找到类似地址列表的机制。

任何帮助表示感谢。

谢谢。

2 个答案:

答案 0 :(得分:0)

来自不同服务器的GAL需要使用配置文件(IProfAdmin)和帐户管理API(IOlkAccountManager)与相应的商店和帐户相关联。这些接口只能在C ++或Delphi中访问。 您需要从两个存储(IMsgSTore)和地址簿对象(IABContainer)中读取PR_EMSMDB_SECTION_UID。如果需要将其与帐户匹配,则IOlkAccount对象中的PROP_MAPI_EMSMDB_SECTION_UID(0x20070102)属性中将提供相同的值 - 如果单击IOlkAccountManager按钮并双击Exchange帐户,则可以在OutlookSpy中看到它

如果使用Redemption是一个选项,则可以使用RDOExchangeAccount对象,该对象公开GAL,AllAddressLists,PrimaryStore,PublicFolders等属性。

答案 1 :(得分:0)

我使用Account.CurrentUser UID和匹配的AddressList UID来选择正确的列表。 我不知道使用Store是否是一种更好的方法,但这种方法效果很好。

理查德和德米特里谢谢你的帮助。

Dmitry我还要感谢您维护互联网上所有MAPI标签的唯一来源。

代码:

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;
        }
    }
}