C# WebBrowser控件System.AccessViolationException问题

31

我有一个使用内置Web浏览器控件的程序。在使用过程中的某个时候,我不确定是在什么时候,但它似乎是随机的,我会收到以下错误:

System.AccessViolationException

FullText = System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)

有没有人知道为什么我会收到这个错误,并且如何避免它?


如果有人找到了一个一致的解决方案,请告诉我,我会接受它。我通过在应用程序外部打开浏览器而不是浏览器控件来解决了这个问题。 - Aaron Smith
2
有没有办法将问题的所有权移交给其他人?我已经不再工作在这个系统上,因此永远不会在这里接受答案... - Aaron Smith
8个回答

7
我们最近在几个客户的机器上遇到了类似的问题。问题最终被确认是某些环境中MSHTML控件的一个漏洞。该问题的常见症状似乎是jscript.dll库的注册损坏。
以下是可能有助于诊断是否存在相同问题的症状- jscript.dll未在调试器的模块列表中列出,并且未被进程加载; 崩溃的本地堆栈跟踪如下:
mshtml!CRootTracker::CollectGarbageInternal+0xd
mshtml!CDoc::ReduceMemoryPressureTask+0x29
mshtml!CStackPtrAry<unsigned long,12>::GetStackSize+0xb6
mshtml!GlobalWndProc+0x183
USER32!InternalCallWinProc+0x23
USER32!UserCallWinProcCheckWow+0x109
USER32!DispatchMessageWorker+0x3bc
USER32!DispatchMessageW+0xf

解决方法是重新注册jscript.dll库,这样崩溃问题就会消失。

重新注册库的方法如下(示例适用于64位Windows,否则只需要第一行):

C:\Windows\System32\regsvr32.exe C:\Windows\System32\jscript.dll
C:\Windows\SysWOW64\regsvr32.exe C:\Windows\SysWOW64\jscript.dll

两个命令都需要以“管理员身份运行”。

4
在尝试访问WebBrowser.ReadyState和WebBrowser.Document时,我在不同场合遇到了这个异常。这些异常只在Windows XP 32位系统上出现。在其他解决方案无效的情况下,这似乎是一个线程问题。我在访问网页浏览器控件的任何代码块周围添加了互斥锁,这似乎解决了问题。

2
经过10个小时的调试和搜索,这是帮助我的东西。谢谢!顺便说一句,我在Windows 7中遇到了异常。 - Martynas

3
我的直觉告诉我,在导航到文档之前,您正在尝试操纵该文档。在更改文档文本或HTML之前,请尝试导航到“about:blank”。
如果您已经执行了导航,请注意导航是异步的,因此您需要监视浏览器事件以便检测导航何时完成。否则,您可能会在文档不存在时尝试写入文档。

1
我并不是在写入文档。我只是将一个URL传递给Web浏览器。我还有一个返回和刷新按钮。我并没有在任何时候操纵文档中的文本或HTML。 - Aaron Smith

1

我们也遇到了这个问题。不稳定的是,我们会得到这个异常。

以下是一些问题,以帮助缩小范围:您是否直接使用任何mshtml接口(例如mshtml.dll)?是否直接进行任何COM互操作?

我们发现调用某些COM MSHTML接口不正确可能会导致此问题。

我们还发现,错误地执行COM封送可能会导致此问题。

如果内置WebBrowser使用的MSHTML接口导入中存在错误,则可能会导致此问题。

从另一个域访问文档IFRAME元素可能会导致此问题。

当文档还没有准备好时进行WebBrowser调用也可能会导致此问题。


0

这似乎是一个Vista问题,我的C# webBrowser1打开了一个运行Java小程序的网页,该网页又打开了一个运行ActiveX应用/脚本的外部IE网页。

当ActiveX脚本尝试更新到C#应用程序的内存时,Vista中的DEP“数据执行预防”将此操作标记为敌对/病毒,并以System.AccessViolationException: Attempted to read or write protected memory结束程序。这通常表明其他内存已损坏。

我的解决方法是在cmd中使用以下命令关闭Vista中的DEP:

"bcdedit.exe /set {current} nx AlwaysOff"

并重新启动机器。

XP也运行DEP,因此在某些情况下,我想这里也可能发生。 要测试是否为DEP问题,请执行以下操作。

右键单击“My Computer” 选择“属性”和“高级” 在“启动和恢复”下,单击“设置” 现在点击“编辑” 记事本刚刚开始。只需将以下行替换为: 代码: noexecute选项n改为AlwaysOff 重新启动计算机以完成交易。

如果要重新激活DEP,只需进行反向操作,如下所示:

替换为 引用: AlwaysOff noexecute = noexecute = optin


这也会在XP机器上发生。 - Aaron Smith
XP也运行DEP,所以我会在调试时尝试关闭DEP来查看是否是问题的原因。 - Darkmage

0
只是一个建议,我对此并不是专家,但在以前的应用程序中经常使用WebBrowser,为什么不编写一个函数,在尝试传递浏览器任何内容之前等待1秒钟,并始终事先检查readystate呢? 这可能会使它变慢一些,但应该可以使它变得更加牢固。 :)

0

您正在导航到的页面是否托管任何ActiveX控件?如果是,其中一个可能存在缺陷。同时,请在IE中检查您的页面。看看它们是否以同样的方式崩溃。这将有助于确定问题是特定于内容还是浏览器控件。


0

最后我只是在浏览器中打开了网页。这样我甚至都不用担心这个问题。不过它抛出这个错误还是很奇怪的。


我原本接受了这个答案,但是有些人可能无法使用它,所以只要其他人还有问题,我就暂时不回答这个问题。 - Aaron Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接