Using Multiple Exchange Accounts
Last modified: November 05, 2011
Applies to: Office 2010 | Outlook 2010 | Visual Studio
Microsoft Outlook 2010 supports integration with multiple exchange e-mail accounts. In Outlook 2010, a user could add two exchange accounts to the same profile and still enjoy rich Exchange features such as the published global address list (GAL), Exchange Out-of-Office configuration, and folder sharing.
Those familiar with the MAPI profile sections for Microsoft Office Outlook 2007 and earlier know that Exchange settings, such as the e-mail user name and server name, are stored in the fixed Exchange Global Profile section, pbGlobalProfileSectionGuid. For more information about the Exchange Global Profile, see How To Open the Global Profile Section. In Outlook 2010, each Exchange account needs its own profile section to store settings, making the pbGlobalProfileSectionGuid obsolete.
Outlook 2010 Exchange settings are still stored in the profile, but a unique identifier for the profile section that contains their settings is dynamically allocated per profile. The location of the Exchange settings in the profile is stored in the PidTagExchangeProfileSectionId Canonical Property, which can be found in the message service profile section of the Exchange account. This property can also be found in the profile section for each provider in this message service of the account. The unique identifier is not stored on the server and will be different across profiles.
Outlook 2010 uses the PidTagExchangeProfileSectionId as a unique identifier to specify an Exchange account. When used in this manner, this unique identifier is known as the emsmdbUID. For some MAPI and Outlook operations, an emsmdbUID might be required to specify which Exchange account should be used for the operation.
In order to support multiple Exchange accounts, you must use some calls to new functions in your code. Replace any call that uses an entryID and either IAddrBook::OpenEntry or IAddrBook::CompareEntryIDs on IMailUser : IMAPIPropand IDistList : IMAPIContainer with one of the following functions.
Any MAPI clients written before the creation of this new emsmdbUID section are still supported. These clients will continue to retrieve the previous global section, pbGlobalProfileSectionGuid. Queries for this profile section will be redirected to one designated Exchange account that handles legacy inquiries. The account that handles the legacy calls can be determined by looking at the message service table and adding a column for PR_EMSMDB_LEGACY. Only one message service will have this set to true, and its PidTagExchangeProfileSectionId is called the legacy emsmdbUID.
Configurable MAPI settings such as the default store and the default account have no effect on which account handles legacy calls. The account that handles the legacy calls cannot be configured.
The emsmdbUID of the legacy account is copied to the Outlook Global Profile Section. If this property does not exist, querying for the message services table will determine what account is the legacy handler and set the value in the Outlook Global Profile Section.
To be clear, the Outlook Global Profile Section differs from the Exchange Global Profile Section, and in Outlook 2010 the Exchange Global Profile Section is no longer really global because you can have multiple Exchange accounts. The Outlook Global Profile section contains properties about Outlook, such as the state of the folder MRU or the state of the global connection.
To resolve addresses correctly with multiple Exchange accounts, use the new functions that take an account context so that calls to the address book search the correct Exchange account.
Some previous address book APIs were deprecated because the APIs were not fully multiple Exchange capable. This account context is usually an emsmdbUID.
In addition to the emsmdbUID, multiple Exchange accounts also have an emsabpUID.
The emsmdbUID value identifies the account context.
The emsabpUID value identifies an Exchange address book provider.
The emsabpUID value is typically used when resolving a recipient. When resolving a recipient using IAddrBook::ResolveName, an Exchange recipient row contains the PR_AB_PROVIDERS (0x3D010102) property, which contains the emsabpUID value. This emsabpUID value identifies the Exchange address book provider for the specific recipient.
If you want to determine the emsabpUID value for a particular emsmdbUID, open up the profile section for the emsmdbUID and get the PR_EMSABP_USER_UID (0x0x3D1A0102) property.
If you are calling IAddrBook::PrepareRecips, make sure that the Exchange recipients in the list that you pass in contain the PR_AB_PROVIDERS property that has the emsabpUID that corresponds to the address book provider that the recipient belongs to. Calling IAddrBook::PrepareRecips on a row that you obtained from IAddrBook::ResolveName requires no additional action, but some code will call IAddrBook::PrepareRecips on rows that contain only the PR_ENTRYID property. Rows in this and similar situations should contain both PR_ENTRYID and PR_AB_PROVIDERS with the PR_AB_PROVIDERS property set to the correct emsabpUID.
A simple description of the process for resolving multiple Exchange accounts is as follows:
Given the service unique identifier, your code looks in the table of the message store of the PR_SERVICE_UID property that matches the one that you have. From there, you can determine the correct PR_MDB_PROVIDER. This row contains the appropriate store.
Given an emsmdbUID, your code looks in the message services table for the row that exposes the PidTagExchangeProfileSectionId that matches the emsmdbUID.