安装 IE9 后使用 WebBrowser 控件的应用程序崩溃

Posted

技术标签:

【中文标题】安装 IE9 后使用 WebBrowser 控件的应用程序崩溃【英文标题】:Application that uses WebBrowser control crashes after installing IE9 【发布时间】:2011-07-20 13:36:39 【问题描述】:

我上周安装了 IE 9,从那以后,我的 c# .net 应用程序崩溃了大约 20% 的时间。除了在 Program.cs Application.Run(new MyMainForm()); 处停止之外,调试器无法显示有用的东西。 , 顺便说一句,主窗体已经显示出来了,所以它不是在主窗体上构建的东西。

我有 Windows7。

The exception thrown is:
"An unhandled exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll

Additional information: Value does not fall within the expected range.

调用堆栈的屏幕截图 -> http://img861.imageshack.us/f/ie9v.png/

在调试器之外运行时,会显示以下信息:

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: myexe.exe
  Application Version:  6.7.6.0
  Application Timestamp:    4d7fdffd
  Fault Module Name:    mshtml.dll
  Fault Module Version: 9.0.8112.16421
  Fault Module Timestamp:   4d76266c
  Exception Code:   c0000005
  Exception Offset: 0012c848
  OS Version:   6.1.7600.2.0.0.256.48
  Locale ID:    1037

And sometimes instead of mshtml.dll it says StackHash_f09d

Problem Event Name: APPCRASH
  Application Name: myexe.exe
  Application Version:  6.7.6.0
  Application Timestamp:    4d7fdffd
  Fault Module Name:    StackHash_f09d
  Fault Module Version: 0.0.0.0
  Fault Module Timestamp:   00000000
  Exception Code:   c0000005
  Exception Offset: 00000000
  OS Version:   6.1.7600.2.0.0.256.48
  Locale ID:    1037

提前致谢

已编辑:

这就是我在windbg中看到的,带有符号:

0:000> kb
ChildEBP RetAddr  Args to Child              
0020eda4 64d54f83 0566c988 00001012 00000000 mshtml!CDoc::ReduceMemoryPressureTask+0x1a
0020edb4 64d54f2c c6b991e4 0020ee78 00000113 mshtml!GWYieldToMsgOnCurrentThread+0x17b
0020edfc 770086ef 00192392 00000012 0000201b mshtml!GlobalWndProc+0x1f2
0020ee28 77008876 64d54afe 00192392 00000113 USER32!InternalCallWinProc+0x23
0020eea0 770089b5 00000000 64d54afe 00192392 USER32!UserCallWinProcCheckWow+0x14b
0020ef00 77008e9c 64d54afe 00000000 0020ef2c USER32!DispatchMessageWorker+0x35e
0020ef10 03b54726 0020ef9c fa69a961 00000000 USER32!DispatchMessageW+0xf
*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v2.0.50727_32\System.Windows.Forms\f92c882fd4e7005c005e208daa04c28d\System.Windows.Forms.ni.dll
WARNING: Frame IP not in any known module. Following frames may be wrong.
0020ef2c 5af78aee 01b743e4 00000001 01ac95cc 0x3b54726
0020efe0 5af78757 00000000 ffffffff 00000000 System_Windows_Forms_ni+0x208aee
0020f038 5af785a1 01b6c610 1f3a000e 00000000 System_Windows_Forms_ni+0x208757
0020f068 5af35911 01bb7d84 0020f10c 003b73d8 System_Windows_Forms_ni+0x2085a1
0020f0e0 6f221b5c 015b1141 00000001 0020f170 System_Windows_Forms_ni+0x1c5911
0020f0f0 6f232209 0020f1c0 00000000 0020f190 mscorwks!CallDescrWorker+0x33
0020f170 6f246511 0020f1c0 00000000 0020f190 mscorwks!CallDescrWorkerWithHandler+0xa3
0020f2b4 6f246544 0032c040 0020f380 0020f34c mscorwks!MethodDesc::CallDescr+0x19c
0020f2d0 6f246562 0032c040 0020f380 0020f34c mscorwks!MethodDesc::CallTargetWorker+0x1f
0020f2e8 6f2b0c45 0020f34c d847bc11 00000000 mscorwks!MethodDescCallSite::CallWithValueTypes+0x1a
0020f44c 6f2b0b65 003239c0 00000001 0020f488 mscorwks!ClassLoader::RunMain+0x223
0020f6b4 6f2b10b5 00000000 d847b3d9 00000001 mscorwks!Assembly::ExecuteMainMethod+0xa6
0020fb84 6f2b129f 013a0000 00000000 d847b389 mscorwks!SystemDomain::ExecuteMainMethod+0x456

=====更新(我不确定,是否应该将其发布为“回答您的问题”)============ 感谢所有努力提供帮助的人,我很感激。

出于绝望,我开始删除代码片段以了解我的代码的哪一部分会影响它(我们以多种形式使用 webbrowser 控件)。在删除对同样使用 webbrowser 控件的 LoginForm 的调用后,问题就消失了。

登录表单承载 webbrowser 控件,它导航到特定 url,例如 /login.php,如果用户已经登录,则使用 ObjectForScripting 从 html 调用表单内部的 UserLoggedIn 方法。当调用 UserLoggedIn 时,如果显示 LoginForm,我们将调用 Close() 来关闭表单。尽管 LoginForm 正在做这一切,但我们并不总是展示它。我们只在 X 秒后未调用 UserLoggedIn() 时才显示它(即用户需要登录)。 出于某种原因,并且感谢 MS 使我们能够调试到 .net 源,当我们调用 Close 时,表单不可见,它实际上是在处理表单及其所有子项,因为 IsHandleCreated 是错误的。现在,从 UserLoggedIn() 调用 Close,这是一个由浏览器控件触发的事件(调用堆栈显示 ieframe.dll、mshtml.dll 等),因此 webbrowser 对象在被调用时被破坏。 解决这个问题的方法是调用 Close,前提是表单是可见的。顺便说一句,我不知道,如果我们不显示表单,为什么 IsHandleCreated 是假的。我试图通过编写一个创建表单的示例来重现它,该表单未显示,但它的 IsHandleCreated 为 true。

---- 来自 Forms.cs -----

        public void Close() 
         

        if (GetState(STATE_CREATINGHANDLE)) 
            throw new InvalidOperationException(SR.GetString(SR.ClosingWhileCreatingHandle, "Close"));

        if (IsHandleCreated) 
            closeReason = CloseReason.UserClosing; 
            SendMessage(NativeMethods.WM_CLOSE, 0, 0);
         
        else 
            // MSDN: When a form is closed, all resources created within the object are closed and the form is disposed.
            // For MDI child: MdiChildren collection gets updated (VSWhidbey# 368642 & 93550) 
            Dispose(); // THIS WAS CALLED WHEN FORM WAS NOT VISIBLE
        
    

【问题讨论】:

这是一个硬崩溃,AccessViolationException,在 IE9 代码中。可以是任何东西。使用独立的 IE9 版本并导航到同一网页以缩小原因。 正如汉斯指出的那样,其他页面也会发生这种情况吗? 它不会在任何特定的 url 上崩溃,当我从我们的 url 更改为“yahoo.com”时也会发生这种情况,从计时器调用 browser.Navigate("xxx"),我不'不知道这是否与它有关。 有什么地方可以下载并试用您的程序吗? 我遇到了类似的问题,但使用 C++ 而不是 .Net 。你能提供一些关于产品和网站的信息吗?您是否在网站和应用程序之间执行任何数据信息?你是怎么做到的? 【参考方案1】:

让您入门的有根据的推测 - 计时器使用线程池线程,即 MTA。如果我不得不猜测我会说它可能与此有关,因为 activex 控件只能从 STA 线程安全地实例化。也许尝试手动创建线程而不是使用计时器线程?

【讨论】:

【参考方案2】:

browser.Navigate("xxx") 被定时器调用

您使用的是哪种计时器?如果计时器触发回调发生在另一个线程上,并且您正在调用浏览器对象上的方法,那么您可能会打开自己的随机崩溃。尝试设置 Control.CheckForIllegalCrossThreadCalls = true;在运行 Application.Run(...) 方法之前,在 Main() 方法中查看它是否崩溃时,您会收到更“正确”的错误消息或相同的消息。

【讨论】:

【参考方案3】:

当 jscript.dll 注册不正确时会发生此崩溃。 ReduceMemoryPressureTask 方法期望它被加载,否则会导致 null 取消引用。修复方法是在受影响的机器上运行 regsvr32 jscript.dll。您可以通过查看加载的模块列表来检查错误,以查看 jscript.dll 是否丢失。这可以通过编程方式或通过Process Explorer 完成。

【讨论】:

【参考方案4】:

异常代码 c0000005 通常表示内存问题。也许它与您的应用程序的 32 位和 64 位区域混淆有关。 我会尝试让您的应用程序在 64 中完全运行,然后完全在 32 中运行,看看会发生什么。 尝试以管理员身份运行,看看是否有任何改变。 此外,您应该在有意义的地方放置 try catch,并在发现错误时重新尝试。 好吧,这些都是建议,所以请尝试一下,看看是否可以为我们提供更多信息。

祝你好运!

【讨论】:

【参考方案5】:

这可能是有原因的,因为 WinForms 在 STA 下运行,但 Web 浏览器需要 MTA。在浏览器控件上方放置一个 try-catch 并检查是否存在 r/w 访问破坏。正如 Oakcool 所说的

【讨论】:

【参考方案6】:

我遇到了这方面的问题,主要是由于违反了权限。 程序在管理员级别运行,浏览器在用户级别运行,反之亦然。 需要研究的东西

【讨论】:

【参考方案7】:

自从我安装了 ie9 后,我得到了同样的错误/崩溃。仅当页面上有 youtube 电影时才会发生这种情况。比它挂起/崩溃的窗口与你得到 Jack Juiceson 的窗口完全相同。

但在“故障模块名称”后面我没有得到 mshtml.dll,我得到一个 d3d9.dll 或类似的东西。很奇怪。

【讨论】:

这完全不相关。请务必升级到最新版本的 Flash,如果仍然出现崩溃,请单击工具 > Internet 选项 > 高级,然后勾选“使用软件渲染”框。

以上是关于安装 IE9 后使用 WebBrowser 控件的应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

WebBrowser控件默认使用IE9,IE10的方法

怎样把WebBrowser控件放到IE9成标准?

WebBrowser(超文本浏览框)控件默认使用IE9,IE10的方法

WebBrowser 控件和 JavaScript 错误

WebBrowser 控件不呈现某些页面

delphi webbrowser,如何调整webbrowser里面打开网页的大小,或者使打开的内容适应webbrowser控件的大小。