1

У меня есть приложение в Delphi XE2 (работает на Win7 x64, MSIE 10.0.9200.16635), которое создает несколько потоков. Каждый поток создает интерфейс IWebBrowser2, который затем переходит на веб-страницу, сохраняет его на диск, удаляет интерфейс IWebBrowser2 и завершает поток. Для свойства «Без звука» веб-браузера установлено значение true. Проблема заключается в том, что с определенной URL, я получаю эти ошибки после завершения рабочей нити (например, веб-браузер не должен существовать больше: Screenshot1 Screenshot2Delphi - не удается вызвать диалоги ошибок JavaScript с помощью IWebBrowser2 в многопоточном приложении

Это JavaScript ошибка, первый говорит: «Ожидается функция», URL разрешения: //ieframe.dll/preview.js, а другой - «Отказ (сервер [не серверное приложение]) недоступен и исчез, все соединения недействительны, а вызов не выполнялся». URL-адрес тот же, res: //ieframe.dll/preview.js. Все, что мне нужно, это подавить эти диалоговые окна с ошибками, но я не могу. У IWebBrowser2 нет свойства ScriptErrorsSuppressed, поэтому я не могу идти этим путем. Иногда я получаю первое сообщение, а иногда и другое. Я три дня искал ответа, и я беспомощен. потоки выполняют свою работу, у меня нет утечек памяти - единственная проблема заключается в этих диалоговых окнах ошибок. Я отключил отладку и сообщения об ошибках в расширенных параметрах MSIE, но это не помогает. Я думаю, что здесь может случиться так, что после того, как поток и все объекты «официально» удалены, javascript со страницы все еще выполняется где-то в памяти. Затем он обнаруживает, что объект браузера исчезает, и именно поэтому я, вероятно, получить это второе сообщение «вызываемый абонент (сервер ...»

Вот мой код:.

function AtlAxAttachControl(const pControl: IUnknown; 
    hWnd: HWND; ppUnkContainer: IUnknown): DWORD; stdcall; external 'ATL.DLL'; 

procedure TWPThread.Execute; 
const 
    CLSID_InternetExplorer: TGUID = '{8856F961-340A-11D0-A96B-00C04FD705A2}'; 
var 
    WndClass: TWndClassEx; 
    WebBrowser: IWebBrowser2; 
    Handle: HWND; 
    Msg:TMsg; 
    iall:IHTMLElement; 
begin 
    FillChar(WndClass, SizeOf(WndClass), 0); 
    with WndClass do 
    begin 
    cbSize := SizeOf(WndClass); 
    lpszClassName := 'MESSAGE_ONLY_WINDOW'; 
    lpfnWndProc := @DefWindowProc; 
    end; 
    RegisterClassEx(WndClass); 
    Handle := CreateWindowEx(0, WndClass.lpszClassName, nil, 0, 0, 0, 0, 0, DWORD(HWND_MESSAGE), 0, 0, nil); 
    if (Handle = 0) then raise Exception.Create('CreateWindowEx'); 
    try 
    CoInitializeEx(nil, COINIT_APARTMENTTHREADED); 
    if (CoCreateInstance(CLSID_InternetExplorer, nil, CLSCTX_INPROC_SERVER, IID_IWebBrowser2, WebBrowser) <> S_OK) then raise Exception.Create('CoCreateInstance'); 
    try 
    AtlAxAttachControl(WebBrowser, Handle, nil); 
    WebBrowser.Silent:=True; 
    WebBrowser.Navigate('http://investing.money.msn.com/investments/stock-report?CR=1&AF=1&IH=1&AIE=1&AIR=1&FRH=1&FRK=1&ISA=1&ISQ=1&BSA=1&BSQ=1&CFA=1&CFQ=1&TYS=1&ITT=1&ITP=1&Type=Equity&Symbol=AAN', EmptyParam, EmptyParam, EmptyParam, EmptyParam) ; 
    while (WebBrowser.ReadyState <> READYSTATE_COMPLETE) do 
    begin 
    while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do DispatchMessage(Msg); 
    Sleep(1); 
    end; 
    // MessageBoxW(0, PWideChar((wb.Document as IHTMLDocument2).title), '', 0); 
    iall := (WebBrowser.Document AS IHTMLDocument2).body; 
    while iall.parentElement <> nil do iall := iall.parentElement; 
    Form1.Memo1.Text := iall.outerHTML; 
    Form1.Memo1.Lines.SaveToFile('D:\memo.html'); 
    finally 
    WebBrowser:=Nil; 
    end; 
    finally 
    DestroyWindow(Handle); 
    CoUninitialize; 
    end; 
end; 


procedure TForm1.Button1Click(Sender: TObject); 
begin 
TWPThread.Create; 
end; 

Что я делаю неправильно Есть ли способ, который может помешать появлению этих диалоговых окон с ошибками? Я думал о том, чтобы вводить свой собственный JavaScript на загружаемой странице - например, мой собственный обработчик window.onerror, который бы подавлял ошибку, но я не уверен, что это правильный путь, а также я плохо разбираюсь в JavaScript, особенно при использовании этого кода.

Любая помощь очень ценится, спасибо! Ace.

+1

на самом деле не Anser, но вы можете остановить боль себя и использовать TEmbeddedWB из http://bsalsa.com, или принять посмотреть на исходный код и понять, что это не так simple ... – whosrdaddy

+1

Если вы хотите получать содержимое страницы и сохранять ее на диск, почему бы вам не использовать компонент Indy 'TIdHTTP'? – LightBulb

+0

Что говорит LightBulb. Весь ваш подход ошибочен. Используйте правильный подход, и эта проблема не существует. –

ответ

0

Вы можете отключить отладчик сценариев, используя реестр, дополнительно с использованием свойства «Без звука», в C#, которое будет выглядеть (код, взятый из CSWebBrowserSuppressError). Это можно сделать один раз только при запуске приложения. А также посмотрим на @locster answer

var newValue = value ? "yes" : "no"; 

using (RegistryKey ieMainKey = Registry.CurrentUser.OpenSubKey(
    @"Software\Microsoft\Internet Explorer\Main", true)) 
{ 
    string keyvalue = ieMainKey.GetValue("Disable Script Debugger") as string; 
    if (!keyvalue.Equals(newValue, StringComparison.OrdinalIgnoreCase)) 
    { 
     ieMainKey.SetValue("Disable Script Debugger", newValue); 
    } 
}