【问题标题】:.NET 4 WebBrowser hangs.NET 4 WebBrowser 挂起
【发布时间】:2013-07-27 12:55:03
【问题描述】:

我正在使用 .NET 4 并尝试通过 Web 浏览器控件(WPF 和/或 WinForms)使用 StackApps 站点的桌面身份验证来开发用于访问 StackOverflow (https://stackapps.com/questions/4215/stackapp-nntp-bridge-for-accessing-stackexchange-forums-like-stackoverflow) 的 NNTP 桥。

显示“StackExchange Login”页面后,似乎无法登录,因为网络浏览器挂起。 我使用以下网址: https://stackexchange.com/oauth/dialog?client_id=1736&scope=no_expiry&redirect_uri=https://stackexchange.com/oauth/login_success

它在普通的 IE 浏览器中有效,但在 WinForms 或 WPF 窗口中无效...有谁知道问题出在哪里?

复制很简单:

  1. 创建一个 WinForms 项目
  2. 将“WebBrowser”控件添加到对话框中
  3. 双击 Form1
  4. 添加以下代码

    private void Form1_Load(object sender, EventArgs e)
    {
      webBrowser1.Navigate("https://stackexchange.com/oauth/dialog?client_id=1736&scope=no_expiry&redirect_uri=https://stackexchange.com/oauth/login_success");
    }
    
  5. 启动应用程序

  6. 按“使用 Stack Exchange 登录”帐户符号登录
  7. 新页面被加载;显示正确,但无法输入登录名;窗户挂了……

同样的情况,如果我使用 WPF-App 和 WPF-WebBrowser-Control...它似乎陷入了 JavaScript 的无限循环...

关于如何解决这个问题的任何提示?

或者是否可以在 WebBrowser-Control 中调试 JavaScript???

【问题讨论】:

  • 有人无法重现这个问题吗?
  • 您可以试试这个 -> 将您的“WebBrowser”控件的属性“ScriptErrorsSuppressed”设置为“True”。如果这没有帮助,请尝试将您的 Internet Explorer 更新到较新的版本。之后,“WebBrowser”控件将使用较新版本的 IE,也许会更好。只是前两个想法:) 我希望我有所帮助。编辑:这个link 和这个link 也可以提供帮助。
  • 我也尝试设置 scriptErrorsSuppressed 属性;它不会改变任何东西...我在 Win7 上安装了最新版本的 IE...
  • 那么指向 IE WebBrowser 控件替代方案(Firefox 核心、Chrome 核心)的链接呢?如果您坚持使用 IE,我深表歉意。我不知道如何进一步帮助。编辑:例如,您的应用中用于 Firefox WebBrowser 核心的壁虎:code.google.com/p/geckofx
  • 我会尝试替代方案...但大多数情况下它们都不是很容易部署...我会看看并检查一下...但是如果页面也很好将解决javascript无限循环;)

标签: c# .net wpf winforms webbrowser-control


【解决方案1】:

修复 WebBrowser 控件

我在尝试登录时也遇到了 WebBrowser 控件处理的问题。

虽然在 IE (11) 中请求令牌有效,但我发现当我将其置于 IE 7 仿真模式时,IE 本身也会挂起。这表明我之前尝试让 WebBrowser 控件使用更新版本的尝试失败了。

我找到了这篇文章Web Browser Control Specifying the IE Version,它建议对于64位模式下的32位应用程序,您需要设置不同的注册表值。

所以现在,我在注册表中添加了两个值:

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

在这两个文件中,我添加了一个名为“MyExecutable.exe”的 DWORD 值(其中 MyExecutable 是我的可执行文件的实际名称)。它们每个的值都是 9000,适用于 IE9 及更高版本。使用 RegEdit 进行测试时要小心,它将默认为十六进制而不是十进制。另外,请确保它是 DWORD 值,而不是任何其他类型。

这似乎可以解决问题。我现在可以运行应用程序,完成登录过程,最终我被重定向到我指定的 url,然后我可以使用 webbrowser 控件的 OnNavigate 事件来捕获它。

遗留问题

它实际上并不完美。我第一次也被重定向到某个 OpenID 页面,但至少表单没有挂起。在随后的尝试中,显然会记住登录(之前成功),并且我收到消息“导航到网页已取消”,其中包含用于刷新页面的链接。当我单击该链接时,我会立即重定向到我在请求登录表单时指定的 redirect_url。至少那部分有效,我得到了一个实际的 access_token 和一个到期时间,所以现在我很高兴。

更新:经过一番测试,原来上次登录被记住了。这会导致请求 uri 立即定向到 redirect_uri。我使用 OnBeforeNavigate 事件来检测这一点,但在这种情况下它不会被触发。我现在链接了 NavigateComplete2 事件,并且在这种情况下触发了该事件。

为 .NET 修复?

我认为 .NET 的解决方案应该是相同的:将可执行文件(以及 MyExecutabl.vshost.exe 以及用于 Visual Studio 中的调试目的)添加到第一个键。如果它是在 62 位 Windows 上运行的 32 位可执行文件,您可能还需要将其添加到第二个键中,尽管我确定该规则是否也适用于 .NET。我不是每天都在做 C#,我首先尝试让它在 Delphi 中工作,但如果我有时间在 C# 中测试它,我会在这里发布更新。

最后,如果实际问题能得到解决,JavaScript 也能在 IE7 模式下工作,那就太好了,但至少这似乎是一个合适的解决方法。

【讨论】:

    【解决方案2】:

    很遗憾,我不是 JavaScript 开发人员,所以我只能尝试向您解释如何调试在 WebBrowser 控件中执行的 JavaScript。

    这种方式是针对微软Visual Studio的,不知道Delphi能不能提供类似的功能。

    1. 在 Internet Explorer 设置中启用脚本调试Internet Explorer其他)。
    2. 在 Internet Explorer 设置中禁用友好的 HTTP 消息
    3. 在 Internet Explorer 设置中启用显示有关每个脚本错误的通知
    4. 在 Visual Studio 中,无需调试(即,Ctrl + F5)启动您的 WebBrowser 托管应用程序。
    5. 在 Visual Studio 中,转到 Debug → Attach to Process… 并在列表中选择您的应用程序。
    6. 点击附加到:字段右侧的选择...按钮并选择脚本代码
    7. 点击附加按钮。 Visual Studio 启动脚本调试器。
    8. 在您的应用程序中,通过按 Login with Stack Exchange 帐户符号导航到死锁页面。
    9. 转到 Visual Studio 并按调试工具栏上的暂停按钮。

    现在您可以查看您的脚本代码并调查代码本身、调用堆栈、变量值等等。你也可以设置断点。也许你可以找到脚本挂起的地方。正如我之前所说,我不是网络开发人员,无法为您提供帮助……

    更新:

    我想我可以向您提出一个可行的解决方案。 我的调查显示WebBrowser 在以 IE7 模式呈现内容时会挂起(即使您的系统中有 IE10 也是默认模式)。您应该强制它切换到 IE9 模式。在 IE9 模式下,页面渲染良好,不会导致脚本陷入死循环。

    您可以使用以下方法之一将 WebBrowser 切换到 IE9 模式:

    1. 在 Windows 注册表中为您的应用程序定义全局浏览器模拟模式。

    对于 32 位操作系统,请转至 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

    对于 64 位操作系统,请使用 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

    在此节点中,创建一个名为 YourApplicationExeName.exe 的新 DWORD 参数,其值为 9000 (0x2710)。如果您希望它在 Visual Studio 调试模式下工作,您可以为您的 *.vshost.exe 可执行文件创建另一个条目。

    1. 操作WebBrowser 的源以将其切换到IE9 模式。

    这会更复杂。您需要更改 html 文档的 <head> 标记,添加一个新的 <meta> 标记,最好作为第一个元素:<meta http-equiv="X-UA-Compatible" content="IE=9"/>。 这将导致WebBrowser 在文档呈现上切换其模式。由于您无法在文档呈现后更改兼容模式,因此您可以使用代理作为WebBrowser 的来源,因此该代理将添加标头。

    我已经用第一种方法成功地测试了这一点,第二种方法也应该可以工作。 希望对您有所帮助!

    【讨论】:

    • 谢谢,我可以试试这个,但即使我发现了一个错误,我也不知道如何解决这个问题,因为这个脚本是 StackApp/StackExchange 登录表单的一部分。
    • 也许您知道您可以在浏览器设置等中更改什么,这样脚本就不会陷入无限循环。
    • 刚刚用我已经在我的机器上成功测试过的建议解决方案更新了答案。
    • 谢谢,我自己发现了选项 1 并将其放入答案中。我真的不知道如何测试选项 2,但相对于 1,这似乎是一种繁琐的方法。感谢您的所有努力!
    【解决方案3】:

    项目+属性,调试选项卡,勾选“启用本机代码调试”选项。确保您已启用 Microsoft 符号服务器(工具 + 选项、调试、符号),我知道您这样做了 :)

    您现在可以使用 Debug + Break All 来查看浏览器内部发生了什么。反复这样做以获得土地的布局。您会看到 Javascript 正在执行 (jscript8.dll) 并不断强制布局引擎重新计算布局,但从未完成工作。

    浏览器通常容易受到陷入无限循环的 Javascript 的攻击。常规浏览器往往会在几十秒后弹出一个对话框以允许用户中止 JS,但 WebBrowser 没有该功能。它也没有开发工具,所以调试 JS 也不会是一件大喜事。这将很难解决。

    您可以考虑改用 OAuth 2.0 api。使用注意事项在this web page。究竟如何将它与 WebBrowser 集成对我来说有点模糊,我没有测试这个的密钥。在Stackapps site 寻求帮助。您可能不是第一个遇到此问题的 SE api 用户。

    【讨论】:

    • 我已经在 stackapps 网站上问过:stackapps.com/questions/4244/desktop-login-webbrowser-hangs-net 但他们将我重定向到 C# ;) 所以我会再次尝试在那里寻求帮助......似乎没有使用桌面身份验证很多时候......也许不是在Windows下......我也尝试过IE兼容性ode,但也许我使用了wearg值......
    • 我不知道如何直接使用 OAuth...我也不知道这是否受支持...据我所知是在服务器中完成的登录,因此总是需要网址...如果您有任何链接会很棒...
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多