WebBrowser (MSIE) - захватывает ошибки JS, используя Exec из IOleCommandTarget - PullRequest
4 голосов
/ 27 марта 2011

Мне нужно перехватить ошибки сценария в элементе управления ActiveX MS IE (дублирован как WebBrowser).

На мой взгляд, это достигается путем реализации интерфейса IOleCommandTarget в моем приложении и прослушивания OLECMDID_SHOWSCRIPTERROR .

Я сделал выше, и я знаю, что это работает, так как мой метод Exec вызывается, но вот проблема;он вызывается только один раз с nCmdID, установленным на $00000037 (OLECMDID_PAGEACTIONBLOCKED), но никогда $00000028 (OLECMDID_SHOWSCRIPTERROR).

Чтобы вызвать эту ошибку, я использовалэтот код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>TEST SCRIPT</title>
    </head><body>
        <script type="text/javascript">
            document.body.style.background='yellow';
            setTimeout(function(){
                document.body.style.background='red';
                causeERROR(); // purposefully undefined function
                document.body.style.background='green';
            },500);
        </script>
    </body>
</html>

Приведенный выше код показывает желтую страницу, затем через несколько миллисекунд - красную и, если выполнение скрипта продолжается (после возникновения ошибки), она должна быть зеленой.

Сразу после покраснения я получаю диалоговое окно с сообщением об ошибке сценария MSIE, и все в порядке.Но мой метод Exec не запускается.

Примечание: Вышеуказанная ошибка с задержкой предназначена для обеспечения ошибки времени выполнения, а не ошибки загрузки страницы, на всякий случай, если это имеет значение.

Моя IOleCommandTarget реализация выглядит следующим образом (Delphi):

type
  TNulWBContainer = class(TWebBrowser, IUnknown, IOleClientSite,
                          IDocHostUIHandler, IDispatch, IOleCommandTarget)
  protected
    { OTHER STUFF }
    {IOleCommandTarget Interface}
    function QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
      prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
    function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
      const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
    end;

implementation

{ OTHER STUFF }

function TNulWBContainer.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
  prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
begin
  prgCmds.cmdf := OLECMDF_ENABLED;
  Result := S_OK; //inherited QueryStatus(CmdGroup,cCmds,prgCmds,CmdText);
end;

function TNulWBContainer.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
  const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
begin
  ShowMessage('nCmdID=$'+IntToHex(nCmdID,8));
  Result:=OLECMDERR_E_UNKNOWNGROUP;
end;

end.

Я запускаю этот материал на Windows 7 Ult 64bit.У меня установлен MS Script Debugger и MSIE «Отключить отладку сценариев для nnn» отключен для обеих опций.MSIE: v9.0.8112.16421 .

Примечание: Я не пометил это под Delphi, поскольку все родные языки можно легко перевести на Delphi, даженекоторые управляемые языки, такие как VB или C #.


Ссылки по теме:

1 Ответ

2 голосов
/ 28 марта 2011

Это самая глупая ошибка в истории! Нет, серьезно!

MS, вы действительно сосете на этом;)

Я все заработал, мой код с самого начала был корректным ( т.е. два дня назад;) )

Как сказано в статье, вам нужно Disable Script Debugging (Internet Explorer) не проверено .

НО Disable Script Debugging (Other) необходимо проверить (в Свойствах обозревателя> Дополнительно).

Странно, да? Отсюда я получил совет: http://www.delphigroups.info/2/9/938468.html (2005-04-29 09:42:48 PM).

Да, это 6 лет назад. Я удивлен, нет, поражен, что такое могло быть возможно и нигде не задокументировано.

Редактировать: Программное исправление:

uses Registry;

// ...

  with TRegistry.Create do
    try
      RootKey:=HKEY_CURRENT_USER;
      if OpenKey('\Software\Microsoft\Internet Explorer\Main',False) then begin
        WriteString('DisableScriptDebuggerIE','no');
        WriteString('Disable Script Debugger','yes');
        CloseKey;
      end;
    finally
      Free;
    end;

// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...