Reading JS Variable from BHO in IE9

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?

windows
com
ole
bho
internet-explorer-9
asked on Stack Overflow Mar 1, 2011 by Marten

1 Answer

3

While IDispatch->GetIDsOfNames() fails to get a Dispatch ID of the variable in IE9, it turns out that using the result from get_Script() as IDispatchEx instead of IDispatch and calling:

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

instead of

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

does result in a valid and usable id to be used with pDispEx->Invoke().

To get an IDispatchEx pointer, I used:

CComPtr<IDispatchEx> pDispEx;
hr = pDisp->QueryInterface(IID_IDispatchEx, (void**)&pDispEx);`
answered on Stack Overflow Mar 22, 2011 by Marten

User contributions licensed under CC BY-SA 3.0