我在Delphi XE2中有一个应用程序(运行在Win7 x64上,安装了MSIE 10.0.92061.6635),它可以创建多个线程。每个线程创建IWebBrowser2接口,然后导航到网页,将其保存到磁盘,删除IWebBrowser2接口并终止线程。web浏览器的"静音"属性设置为true。问题是,对于某些URL,我在终止工作线程后会出现这些错误(例如,web浏览器不应该再存在了:屏幕截图1屏幕截图2
这些都是JavaScript错误,第一个错误是"预期函数",URLres://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,尤其是这种代码注入的东西。
非常感谢您的帮助,谢谢!王牌
您可以使用注册表禁用脚本调试器,此外还可以使用c#中的"Silent"属性(代码取自CSWebBrowserSuppressError)。这只能在应用程序启动时完成一次。我们也可以看看@locster答案
var newValue = value ? "yes" : "no";
using (RegistryKey ieMainKey = Registry.CurrentUser.OpenSubKey(
@"SoftwareMicrosoftInternet ExplorerMain", true))
{
string keyvalue = ieMainKey.GetValue("Disable Script Debugger") as string;
if (!keyvalue.Equals(newValue, StringComparison.OrdinalIgnoreCase))
{
ieMainKey.SetValue("Disable Script Debugger", newValue);
}
}