如何使用Outlook对象模型C ++禁用Outlook安全性弹出窗口

时间:2013-03-28 13:26:49

标签: c++ security email outlook mapi

我们正在使用Outlook对象模型来阅读所有Outlook联系人:

  • Outlook对象模型
  • Microsoft Office 2010 64位
  • Windows 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安全弹出窗口。

请在这些代码块内的注释中查看我们的发现。

1 个答案:

答案 0 :(得分:0)

查看与OutlookSpy的联系人 - 单击“IMessage”按钮,查看您要检索的属性。

调用GetProps时,可以对PR_GIVEN_NAME和PR_SURNAME进行硬编码(这些不是命名属性)。对于Email1AddressType和Email1Address,您需要使用OutlookSpy显示的相应GUID和ID来首先找出属性标记(使用GetIDsFromNames)。