すべての Outlook 連絡先を読み取るために、次のように Outlook オブジェクト モデルを使用しています。
- Outlook オブジェクト モデル
- マイクロソフト オフィス 2010 64 ビット
- ウィンドウズ7アルティメイト
#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 Security ポップアップ メッセージを取り除くために、インターネットで次のような解決策を見つけました。
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 オブジェクト モデルを使用する方法です。
これらのコード ブロック内のコメントでも調査結果を確認してください。