Мы используем объектную модель Outlook следующим образом для чтения всех контактов Outlook:
#import "mso.dll" named_guids
#import "msoutl.olb" no_namespace
...
...
void OutlookFeaturesImpl::getContactsFromOutlook()
{
_NameSpacePtr pNameSpace = m_ApplicationPtr->GetNamespace(_bstr_t("MAPI"));
....
MAPIFolderPtr pFolder = pNameSpace->GetDefaultFolder(olFolderContacts);
if( pFolder )
{
....
_ItemsPtr pItems = pFolder->GetItems();
....
_ContactItemPtr contact = pItems->Find(bstrFilter);
if( contact )
{
collectContactDetails(contact)
}
}
}
void OutlookFeaturesImpl::collectContactDetails( _ContactItemPtr pContact )
{
// The following 2 lines work fine. No Outlook security popup.
_bstr_t bstrFirstName = pContact->GetFirstName();
_bstr_t bstrLastName = pContact->GetLastName();
// The following calls to get Email address and Properties trigger the Outlooks' security prompt since they are part of the "Outlook security object model guard" as you may see from this link:
// http://www.vbforums.com/showthread.php?402086-FAQ-s-OD-Why-do-I-get-an-Outlook-Security-Prompt
_bstr_t emailAddType = pContact->GetEmail1AddressType();
_bstr_t bstrEmailAddress = pContact->GetEmail1Address();
_PropertyAccessorPtr p = pContact->GetPropertyAccessor();
}
Чтобы избавиться от всплывающего сообщения безопасности Outlook, я нашел какое-то решение в Интернете:
void OutlookFeaturesImpl::collectContactDetails( _ContactItemPtr pContact )
{
CComQIPtr pIMessage;
// we should use late binding when calling GetMAPIOBJECT()
CComQIPtr pIDispatch(pContact);
OLECHAR FAR* szMember = L"MAPIOBJECT";
DISPID dispID;
hr = pIDispatch->GetIDsOfNames( IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispID );
if( SUCCEEDED(hr) )
{
DISPPARAMS params = {0, 0, 0, 0};
params.cArgs = 0;
_variant_t varResult;
hr = pIDispatch->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL );
if( SUCCEEDED(hr) )
{
pIMessage = varResult; // pIMessage will be NULL after this assignment
}
}
if( pIMessage ) // It is NULL and hence does not go inside
{
LPSPropTagArray lpNamedPropTags = NULL;
MAPINAMEID NamedID = {0};
LPMAPINAMEID lpNamedID = &NamedID;
NamedID.lpguid = (LPGUID)&PSETID_Address;
NamedID.ulKind = MNID_ID;
NamedID.Kind.lID = dispidEmailOriginalDisplayName;
hr = pIMessage->GetIDsFromNames(1, &lpNamedID, NULL, &lpNamedPropTags);
if (SUCCEEDED(hr) && lpNamedPropTags)
{
SPropValue* pPropValue = NULL;
SPropTagArray sPropTagArray;
sPropTagArray.cValues = 1;
sPropTagArray.aulPropTag[0] = CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[0],PT_STRING8);
ULONG cProps = 0;
hr = pIMessage->GetProps(&sPropTagArray, NULL, &cProps, &pPropValue);
if (SUCCEEDED(hr) && 1 == cProps && pPropValue && PT_STRING8 == PROP_TYPE(pPropValue[0].ulPropTag) && pPropValue[0].Value.lpszA)
{
_bstr_t bstrEmail1Address = pPropValue->Value.lpszA;
}
}
}
}
ПРИМЕЧАНИЕ. Это волшебные строки, использованные в приведенном выше коде:
#define dispidEmailOriginalDisplayName 0x8084
const GUID PSETID_Address = {0x00062004, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
Вопрос в том, что использовать с объектной моделью Outlook с нашим существующим кодом (который показан выше в блоках кода), чтобы избежать всплывающего окна безопасности Outlook.
Пожалуйста, проверьте наши выводы в комментариях внутри этих блоков кода.
Посмотрите на контакт с OutlookSpy — нажмите кнопку IMessage, посмотрите на свойства, которые вы пытаетесь получить.
При вызове GetProps PR_GIVEN_NAME и PR_SURNAME могут быть жестко закодированы (это не именованные свойства). Для Email1AddressType и Email1Address вам нужно будет использовать соответствующие GUID и идентификаторы, отображаемые OutlookSpy, чтобы сначала выяснить теги свойств (используя GetIDsFromNames).
Других решений пока нет …