对 COM 组件的调用返回了错误 HRESULT E_FAIL

oldhunter 2013-02-20 01:09:06
我用 WebBrowser(.net 2.0内置的类) 来实现网页截图功能,代码正常运行一两天,就会出现异常:对 COM 组件的调用返回了错误 HRESULT E_FAIL。

更离奇的是:一但出现一次,只要不重启程序,程序运行这段代码时,这个异常会一直出现。我不懂 COM组件(WebBrowser)的实现,难道它是 Singleton 模式吗?我明明是每次都释放,下次运行时,再创建一个新实例。

下面是截图这部分的代码:

using (WebBrowser webBrowser = new WebBrowser())
{
webBrowser.ScrollBarsEnabled = false;
webBrowser.ScriptErrorsSuppressed = true;
webBrowser.Navigate(url);

while (webBrowser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}

if (webBrowser.Document.Body.InnerText.Trim() == "")
{
throw new Exception("Document.Body.InnerText 为空,无法完成截图。");
}

if (webBrowser.Document.Body.InnerText.Contains("已取消到该网页的导航"))
{
throw new Exception("加载网页出错:已取消到该网页的导航。无法完成截图。");
}

webBrowser.ClientSize = new Size(this.browserWidth, this.browserHeight);
webBrowser.ScrollBarsEnabled = false;

this.bitmap = new Bitmap(webBrowser.Bounds.Width, webBrowser.Bounds.Height);
webBrowser.BringToFront();
webBrowser.DrawToBitmap(this.bitmap, webBrowser.Bounds); // 将图片截取到全局变量

// 不再要再做缩略图转换,可以提高效率和稳定性。
//bitmap = (Bitmap)bitmap.GetThumbnailImage(thumbnailWidth, thumbnailHeight, null, IntPtr.Zero);
}


另外,CSDN 这个帖子编辑框,一打字快了,怎么这卡?它好像一直在用 ajax 回传东西还是怎么,你们的浏览器这样吗?用着真难受。
...全文
10488 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
shy_z 2014-10-17
  • 打赏
  • 举报
回复
我用的webkit.net也出这个问题
zipyuan 2014-04-10
  • 打赏
  • 举报
回复
你重启一下vs一下试试。我也遇到过这样的问题,我调用的是自定义组件,莫名其妙就出现了那个问题,重启一下就好了。
cliffyanT 2013-06-02
  • 打赏
  • 举报
回复
最近我也遇到这个问题了!不过调用的是其他的组件!
threenewbee 2013-02-23
  • 打赏
  • 举报
回复
webbrowser经常内存泄漏,这和javascript垃圾回收机制不完善有关。
oldhunter 2013-02-23
  • 打赏
  • 举报
回复
引用 8 楼 caozhy 的回复:
webbrowser经常内存泄漏,这和javascript垃圾回收机制不完善有关。
谢谢 caozhy(一看就是牛人),也谢谢上面的 hdt,zanfeng。 那c# 有没有办法操作 webbrowser COM组件的对象?出问题后可以销毁它,重新创建一个对象,它是不是用的对象池? 我这几天为了解决这个问题,翻了很多讲COM原理的书。网上下了一个 COM多线程模型、DCOM——潘爱民.pdf,里面一些截图讲得挺明白。 如果能控制这个COM组件在内存泄露后销毁,就可以了,毕竟我们改变不了它,是MS的东西。
足球中国 2013-02-22
  • 打赏
  • 举报
回复
引用 1 楼 stonespace 的回复:
com组建模型中,组建是独立于调用者的,一般来说,组件有自己的进程,WebBrowser其实在IE浏览器的进程提供的组建服务,你创建一个WebBrowser对象,只是创建了一个访问IE进程的代理对象而已, 不论你new WebBrowser多少次,你访问的都是同一个IE进程, 应该你的IE出故障了,重装IE可能就可以解决问题,
就是就是。 ie出现问题是正常的。
oldhunter 2013-02-22
  • 打赏
  • 举报
回复
引用 5 楼 hdt 的回复:
不要用while (webBrowser.ReadyState != WebBrowserReadyState.Complete) 而是在 webbrowser.documentcommplte事件里面写
为什么呢? 那样也是在等运行完后再做截图处理啊?
真相重于对错 2013-02-20
  • 打赏
  • 举报
回复
不要用while (webBrowser.ReadyState != WebBrowserReadyState.Complete) 而是在 webbrowser.documentcommplte事件里面写
stonespace 2013-02-20
  • 打赏
  • 举报
回复
windows自己都大量引用WebBrowser控件,不要紧的,
引用 2 楼 oldhunter 的回复:
引用 1 楼 stonespace 的回复:com组建模型中,组建是独立于调用者的,一般来说,组件有自己的进程,WebBrowser其实在IE浏览器的进程提供的组建服务,你创建一个WebBrowser对象,只是创建了一个访问IE进程的代理对象而已, 不论你new WebBrowser多少次,你访问的都是同一个IE进程, 应该你的IE出故障了,重装IE可能就可以……
oldhunter 2013-02-20
  • 打赏
  • 举报
回复
对了,我重启程序后,就又好了。但程序运行一两天,就又不行了。必须要重启。
oldhunter 2013-02-20
  • 打赏
  • 举报
回复
引用 1 楼 stonespace 的回复:
com组建模型中,组建是独立于调用者的,一般来说,组件有自己的进程,WebBrowser其实在IE浏览器的进程提供的组建服务,你创建一个WebBrowser对象,只是创建了一个访问IE进程的代理对象而已, 不论你new WebBrowser多少次,你访问的都是同一个IE进程, 应该你的IE出故障了,重装IE可能就可以解决问题,
谢谢 stonespace : 服务器上是新装的IE8(之前是系统自带的IE6),这个要重装吗?另外,像你说的,我调用IE进程的代理过于频繁,会不会有什么瓶颈?我有至少3个以上的线程同时截图。
stonespace 2013-02-20
  • 打赏
  • 举报
回复
com组建模型中,组建是独立于调用者的,一般来说,组件有自己的进程,WebBrowser其实在IE浏览器的进程提供的组建服务,你创建一个WebBrowser对象,只是创建了一个访问IE进程的代理对象而已, 不论你new WebBrowser多少次,你访问的都是同一个IE进程, 应该你的IE出故障了,重装IE可能就可以解决问题,

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧