Reading JS Variable from BHO in IE9

Refresh

December 2018

Views

1.5k time

3

I have an Internet Explorer BHO that can execute a script on the current website and then read variables that have been assigned in that script. Unfortunately, as of IE9 (I tested with the RC), reading the JS variable results in a HRESULT 0x80020006.

The script sets assigns the JS variable as follows:

this.<js_var> = <value>

where this is the current Window object. It is executed using

hr = pWindow->execScript( ccom_js, lang, &vEmpty );

and the JS variable is read using

bool get_js_var( CComPtr<IDispatch> pDisp, LPOLESTR name, VARIANT *dest )
{
  DISPID id;
  HRESULT hr = pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id );
  if ( SUCCEEDED( hr ) ) {
    VariantInit( dest );
    VariantClear( dest );
    DISPPARAMS dp = { 0, 0, 0, 0 };
    hr = pDisp->Invoke( id, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, dest, NULL, NULL );
    if ( SUCCEEDED( hr ) ) {
      return true;
    } else {
      LOG( _T( "failed to get var contents, hresult = 0x%lx" ), hr );
    }
  } else {
    LOG( _T( "failed to get id of var name, hresult = 0x%lx" ), hr );
  }

  return false;
}

where pDisp has been retrieved using document->get_Script( &pDisp );.

This code works fine in previous versions of IE, on Windows XP, Vista and 7. In IE9 the script executes (I can invoke alerts, etc.), but the variable can not be read. What change in IE9 causes this problem?

1 answers

3

Пока IDispatch->GetIDsOfNames()не удается получить диспетчерский идентификатор переменной в IE9, то получается, что используя результат из , get_Script()как IDispatchExвместо того , чтобы IDispatchи вызова:

HRESULT hr = pDispEx->GetDispID( CComBSTR( name ), fdexNameImplicit, &id );

вместо

RESULT hr = pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id );

это приводит к действительному и практичному идентификатору для использования с pDispEx->Invoke().

Чтобы получить IDispatchExуказатель, я использовал:

CComPtr<IDispatchEx> pDispEx;
hr = pDisp->QueryInterface(IID_IDispatchEx, (void**)&pDispEx);`