Чтение переменной JS из BHO в IE9 - PullRequest
3 голосов
/ 01 марта 2011

У меня есть Internet Explorer BHO, который может выполнить сценарий на текущем веб-сайте, а затем прочитать переменные, которые были назначены в этом сценарии.К сожалению, что касается IE9 (я тестировал с RC), чтение переменной JS приводит к HRESULT 0x80020006.

Наборы сценариев назначают переменную JS следующим образом:

this.<js_var> = <value>

где this - текущий объект Window.Он выполняется с использованием

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

, а переменная JS читается с использованием

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;
}

, где pDisp было получено с использованием document->get_Script( &pDisp );.

. Этот код работаетхорошо в предыдущих версиях IE, в Windows XP, Vista и 7. В IE9 скрипт выполняется (я могу вызвать оповещения и т. д.), но переменная не может быть прочитана.Какие изменения в IE9 вызывают эту проблему?

1 Ответ

3 голосов
/ 22 марта 2011

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

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);`
...