2009-09-30 111 views
5

我正在Windows窗体C#项目中使用WebBrowser控件,并想知道是否存在您可以同时运行多少个此类应用程序实例的限制。 (换句话说,不MSFT执行比物理机的限制以外的任何限制 - CPU /内存等)Web浏览器控制限制

+0

我刚刚针对WebBrowser控件的限制发布了一个答案(长一个),并且还想纠正WebBrowser控件的呈现引擎使用当前安装的IE版本引擎的想法(因为它没有) ,并且我已经概述了如何根据你已经安装的内容来预测和查看它用来渲染的版本。 (请参阅我的答案),但基本上,它使用IE 4.0或IE 7.0默认呈现,这可通过注册表进行更改。干杯。 – 2012-02-12 01:20:07

回答

3

WebBrowser控件没有人为限制。

但是,它使用IE的渲染引擎(无论版本安装在最终用户的计算机上),因此它使用了一点点内存。

你想做什么?

如果您正在尝试编写Web浏览器,我建议您使用更好的渲染引擎,例如WebKitGecko

+2

这样的选择涉及到一套权衡。如果您运送WebKit或壁虎,安装将会更大,并且每次发现这些组件的安全错误时,您都必须发布补丁;另一方面,安装IE更新时IE组件会更新 – EricLaw 2009-09-30 03:37:36

+0

正确但是,使用IE引擎他会增加IE6的用户基数http://mashable.com/2009/07/16/ie6-must-die/ – SLaks 2009-09-30 03:41:57

+0

我很清楚其他渲染引擎,以及优点 - 但我需要使用IE。 问题仍然是什么限制?我也期待内存利用率问题,但是当我做了一些测试超过10个实例时,我碰到了某种类型的墙......并且它不是内存,它确实看起来像CPU,但是考虑到机器有8个内核,这没有意义。 – webly 2009-09-30 13:35:39

0

尝试这个代码,看看会发生什么:

int count = 0; 
List<Form> forms = new List<Form>(); 
try 
{ 
    while (true) 
    { 
     Form f = new Form(); 
     WebBrowser wb = new WebBrowser(); 
     f.Controls.Add(wb); 
     f.Show(); 
     wb.Url = new Uri(@"http://www.stackoverflow.com"); 
     forms.Add(f); 
     count++; 
    } 
} 
catch 
{ 
    MessageBox.Show(count.ToString()); 
} 

我会想这是几百个,但我不知道。

+2

将try/catch移到'while'循环的外部,否则你将永远不会停止循环。 – SLaks 2009-09-30 03:24:16

+1

@SLaks:完成。你让我感到羞耻。 :)我实际上正在计算一旦MessageBox弹出,我就会在Visual Studio中点击“停止”按钮。 – MusiGenesis 2009-09-30 03:36:14

+1

@MusiGenesis我恨我们不能按停止当有一个消息框弹出,它迫使我关闭devenv过程几次:(。 – 2012-02-12 00:14:58

38

让我告诉你一些缺点...

[这里的大多数提到的已经回答了或在StackOverflow的我以前的答案部分解决在一定程度上的问题,如果你很好奇,随意浏览我的Web浏览器控制相关答案]。

  1. 检测时,页面被真正做负载是非常难以可靠地做,事实上,你必须采用一系列黑客为了能够做到这一点,一些方法和思路,甚至没有谈过关于在线和不知道,但我花了这个控制与我一起战斗的岁月,我已经想出了一些东西,并已开发出一个代码库,使其工作!如果你需要这方面的帮助,我可以提供更多的细节。

  2. 让我直接告诉你。 默认的渲染引擎webbrowser控件是固定的,以确保所有的 平台兼容。

    基本上,如果您安装的浏览器是IE 7 - IE 9,那么使用的 渲染引擎仅仅是IE 7.0(默认情况下)。

    但是,如果您安装的IE版本是IE 6或更低版本,那么所用的渲染引擎是IE 4.0(而不是开玩笑),除非您自己设置了它,否则它会被设置为 。

    WebBrowser控件使用当前安装的任何 (当前IE版本),但这不是真的,因为他们这样做是为了减少向后兼容性问题。您可以在您的普通浏览器中看到 (作为证明),这确实是您的问题,因为您需要在您的普通浏览器中登录 www.whatsmyuseragent.com,然后在您的WebBrowser控件中再次登录 该网站,您会看到它说 表示MSIE 7.0 :)。

    你可以将其设置为使用互联网 资源管理器的当前安装的版本,无论是使用网页META标记,或者机器,其中WebBrowser控件将运行在编辑注册表 (编辑为 CURRENT_USER和LOCAL_MACHINE会两个工作)。

    因此,出于兼容性原因,默认情况下,它将在IE7标准模式下呈现页面。为防止这种情况发生,请按照我在下面提供的链接讨论META标记方法和注册表编辑方法,以解决这个问题(针对两个32位的32位32位32位32位数字处理器)。该解决方案作为对其他人关于功能不正确或意外工作的问题的回答。阅读问题并不是正确解释/理解答案所必需的。这里是链接:

    Script runs slower in the dotnet WebBrowser control(按Ctrl +单击以在新选项卡中打开)。

  3. 事件系统相当不好,你真的需要知道没有被正确记录的事情以及一些根本没有记录的事情。事实上,就产品设计而言,我已经宣称它是MS最差的产品之一,并且也缺乏他们提供的体面文件。他们的干MSDN样式文档是可笑的。

  4. 坏帧支持,如果你打电话给document.frames.length,你只会在顶层文件下获得帧,而不是所有的帧,你需要编写自己的函数来获得所有的嵌套帧(无限嵌套),我已经做到了这一点,如果你需要帮助。帧检测和引用非常重要,并且在检测页面何时完成加载时起着至关重要的作用。在这种情况下,在WebBrowser控件上使用.Busy和.ReadyState是不够的。事实上,这远远不够。

  5. 没有内置的系统来摆脱每个页面弹出的JavaScript对话框,包括新的IE9对话框,让人们用“你确定要离开这个页面”的消息给人们造成困扰。我已经开发了一些例程来实现这一点,并摆脱它们,基本上,其中一种方法涉及执行从WebBrowser控件发送到HTML页面的JavaScript,指示它摆脱警报,确认,打印对话框(以及获取摆脱我前面提到的新的IE 9对话框)。这些是来自JS的潜在对话框,我基本上运行JavaScript来告诉浏览器.alert函数是空的(即:一个空的方法/函数什么都不做),而且我对所有这些做了完全相同的事情4个来自JavaScript的对话框。当然,如果你已经计算了超过4个盒子(如果你有更多的数量,请随时让我知道)。另外,还有第二种方法可以做到这一点,它不仅可以防止JavaScritp对话框,而且每个对话框都可以显示在浏览器控件中,此方法使用WinHooks,并在之前拦截对话框它会显示出来,您可以从对话框中获取尽可能多的信息(其内容为文本,标题/标题为文本等),并决定是否要显示或取消显示,甚至模拟任何部分的点击的对话框(即:它的任何按钮),所以堆栈认为问题或信息对话框得到了正确的回应。这是一个有趣的方法,我已阅读但尚未尝试,我真的很期待理解WinHook过程,一旦我有一些空闲时间。和往常一样,如果您需要帮助,请随时查看我以前对各种网页浏览器控制问题的回答,因为我已经回答了很多问题,如果不这样做,请告诉我。请记住,这在很大程度上取决于知道页面何时完全加载,这非常困难(但可能,使用未记录的方法,以100%可靠的方式)。所以点1)。将多次涉及相关。

  6. 没有可靠的或简单的方法来控制永久或保存的缓存信息,再一次,您必须开发自己的例程来执行缓存信息所需的任务,以过滤,删除或尝试阻止所有缓存类型,包括本地系统上存储的历史信息,Cookie和实际缓存文件。如果你看看DeleteUrlCacheEntry,它可以让你自己做两种方法,也很确定我有一些以前的答案,讨论如何在StackOverflow上做到这一点。使用DeleteUrlCacheEntry,您可以使用“Cookie:”标签,“Visited:”标签以及仅为普通网址(以“http://”和“https://”开头的项目) (并且是的,https被缓存; |,至少位置信息是无论如何)。还要注意,通过DeleteUrlCacheEntry(以及用于遍历整个缓存的随附的FindFirstUrlCacheEntry/FindNextUrlCacheEntry)可获得的此信息不包括您的实际Internet浏览器历史项目“访问:”站点列表与您的实际历史记录列表是分开的,当您单击Internet Explorer菜单栏上的*符号并进入历史记录部分(从收藏夹部分)时,您会看到。不知道他们为什么这样做,以及确切的形式差异是什么(以及为什么会有差异),但是它列在要找出的事情清单上(请随时在评论中告诉我们)因为“已访问:”列表是您h的网站列表大家访问过,而IE历史记录几乎就是您访问过的网站列表。我认为他们不会区分您手动输入和输入的网站与通过HTML页面或您的浏览器自动搜索的部分或片段(例如通过iframe等,自动重定向,弹出窗口等) ...所以我很难理解这个区别是什么,一旦我发现,我会更新这一点。

  7. 覆盖默认的用户代理程序内置不正确,您可以将自己的用户代理传递到导航方法,但是一旦用户在那里导航,该站点将按照您设置的方式获取您的程序用户代理详细信息但是,这不会永久存在。因此,一旦用户在导航页面上关注链接,WebBrowser控件将继续发送WB控件用于呈现您的网站的实际(真实)用户代理,除非您拦截导航,取消导航并重新导航再次发送自己的用户代理时再次使用.navigate方法。这将无法解释像图像和LINK标记文件等事情,因为您没有获得BeforeNavigate事件,因此您无法拦截它们并修改为它们发送的标题。相反,您需要通过导入一些外部函数urlmon.dll来使用外部解决方案 - 这可以做到100%并且工作完美无瑕,但是,它是另一个附加依赖项(但urlmon.dll包含在迄今为止所有相关的Windows版本中)。

  8. 没有“将所有WB控制活动重定向到此特定帧”属性或方法,尽管您可以并且必须开发如果您需要或需要,唯一的帧支持是TargetFrameName参数与.navigate方法一起使用,您需要获取对它的引用,并手动指示您在那里执行的所有操作,因为用户可以从任何框架中点击事物,并且您不知道或线索,除非你检查它。

  9. 框架指向外部域的站点的跨框架安全性:您可能知道,如果您在abc.com上有一个页面,并且它的iframe中包含来自名为xzy.com的域的源(如大多数广告客户在从他们自己的服务器中继内容时都会这样做),如果您尝试访问该框架,则无论您的应用程序运行在哪种特权下,都会遇到跨框架域安全问题。这很愚蠢,他们甚至不会告诉你,相反,你指向框架的参考文件只是没有任何数据,你将无法使用它,而WB控制也不会告诉你为什么。您将可以访问的只是框架的源URL,就是它,里面没有任何东西。解?那么,您的机器上有一个TypeLib可注册的设备,您可以使用它来覆盖此设置,而不是内置于WB控制中,甚至不会内置到您自己的编程接口中,实际上它是一个外部C例程,您需要通过引用来使用它并注册TypeLib(不知道现在有没有新的方法可以在.NET中使用这种方法)。但是,您还需要在当前的编程环境中编写代码(在您的当前编程环境中编写代码)(在TypeLib注册中使用这些代码的额外代码,因此它不仅仅是调用函数的问题,而是围绕该函数编写更多代码将会使用)。

  10. 打开/关闭JavaScript,打开/关闭导航设置,如导航声音等。如果你正在编写一个网页提取程序,导航声音会让你的用户感到疯狂,打开或关闭这些选项不会内置到WebBrowser控件中,你可以根据需要使用注册表全局更改内容,然后更改它们一旦完成就返回。您需要查看每个与互联网设置相关的设置/选项的reg值。有一些方法可以为您的应用程序实例执行此操作,从InternetSecuritySettings导入例程(我相信),但是再一次没有将其构建到WB中,只是另一系列黑客添加到列表中。

  11. 当然,您需要检测互联网连接是否存在,以及是否有可用连接。 WB控制甚至不会给你一丝希望,尽管这是它工作的重要组成部分。因此,如果您不希望在其他连接上使用MS拨号连接(用于拨号的用户)或互联网向导的令人讨厌的弹出窗口出现每次您的WB控制尝试进行连接或尝试在某处导航,则你将需要使用一个控件来手动尝试和检查连接,并且这个控件必须是MS之外的一个控件,以及一个没有MS API核心的控件(因为MS internet API是API的触发这些弹出框用于互联网连接)。因此,您需要获得一个外部winsocks类型的控件,该控件从头开始不使用winsocks,了解如何使用它,并在每次使用WB执行操作之前尝试检查互联网是否已连接控制。

  12. 当您在处理HTML文档/页面上的元素时,您会得到很多“自动化错误”或“未指定的错误”消息,它们甚至不会告诉您哪里出了错,当有HTML以不推荐的方式完成时,尽管它是浏览器可以处理和阅读并定期处理的方式。例如,如果您的target链接为_top,并且围绕_top部分没有引号,即使浏览器了解并按预期行事,webbrowser控件也会将其放在空中并放弃投掷一个“未指定的错误” - 甚至不告诉你它超级挑剔。所以,你必须确保元素是这样写的:target =“_ top”为了让WB控制行为起来,并且对每个活动文档做出这些改变可能是单调乏味的,你需要如果需要的话,编写一般例程为每个页面执行此操作 - 在文档已满载之后运行的例程(必须可靠地检测才能执行)。如果我不得不挑选最难的东西来正确处理WB控制,那么当页面完全可靠地装载时,它必须被检测到。最重要的是,在WB控制方面,这也是您需要做的最重要的事情,因为几乎所有事情都取决于对此的精确检测。

  13. 它需要一个单独的历史对象,因为如果您在导航过程中选择“无历史记录”,或者找到一种使无历史记录导航工作的方式,则可以确保回退或转发到这些页面将不起作用(即:呼叫.GoBack或.GoForward到这些页面和地址)。一旦从历史记录中删除,或者指定没有为此或特定导航保留历史记录,返回就不可能,除非您重新导航到该页面。他们应该保留内存中的历史记录列表,即使该页面已从全局历史记录中删除(这是唯一没有历史浏览记录的方式),应该可以回溯到该列表。因此,如果您尝试返回,您将(在所有内容之上)得到一个运行时错误,并且只有在最近的.NET时代,他们才提供了一个名为.CanGoBack的方法来检查是否可以返回(如果使用pre.NET),你应该编写代码或者试着保留你的位置(这不容易做,但仍然可行)。

我可以继续从那些东西怎么回事(我认为),但我会留在这一点,现在,但是,除了,这是一个很酷的控制和不开门的一个全新的世界应用程序和想法,你可以发生。正如我在其中几点中指出的那样,这些都是我已经解决的所有问题(还有更多,我需要解决方案时已解决),所以如果您有任何问题或需要任何帮助,请让我知道我会很乐意至少尝试帮助你。

当我试图找出这些东西的时候,没有人会帮助我,因为没有人真正了解这个控制器,所以我不得不一一找出一点点东西。从那时起,它就越来越流行,而且有更多的人使用它(特别是.NET版本提供了渐进式改进)。所以,我很乐意帮助那些以前遇到过的人,因为我记得这是一个可怕而孤独的地方,而MS没有做任何文件记录。这只是他们开发的内部使用,让其他人使用它,而只提供输入/输出参数/参数列表&所有属性,方法和事件的返回值列表,这就是它 - 没有意义或上下文或与之相关的真实代码示例,当然,在解决随之而来的一系列问题方面,没有任何文档明智。

好的,现在这样做,会对这个控件的使用者及其使用感兴趣,所以请随时发表评论。保重。 ERX。

+2

感谢您的出色答案。当页面加载完成时,我也遇到了麻烦。你能否给我提供更多的细节?我已经尝试了很多方法,但仍然无法正常工作 – 2012-02-17 06:25:06

+0

你好,对你承诺提供帮助的修补程序感兴趣,请帮助我的信息 – Smith 2012-05-03 03:15:28

+1

嗨,我很乐意帮助你,但是其中的每一个问题需要提出一个新问题,因此您需要针对您的每个问题提出一个新问题,然后将我指给他们,以便我可以对此作出回应。 – 2012-05-03 08:48:38