Web浏览器控制和指定IE版本

我在很多桌面应用程序中使用Internet Explorer Web浏览器控件来显示文档内容。例如Markdown Monster,Help Builder和WebSurge严重依赖Web浏览器控件来呈现其文档中心甚至是丰富的交互式UI(在主持HTML编辑器的Markdown Monster的情况下)。无论您是仅渲染文档内容,还是与丰富的交互式内容进行交互,HTML都是最常见的文档格式之一,可以显示或与之交互,它是传统表单UI的完美补充。即使在桌面应用程序中,通常比使用标签或编辑框甚至某些WPF文本容器更容易。HTML易于生成,通常可重用,并且易于扩展和分发。Web浏览器控件允许以一种混合并成为应用程序一部分的方式在应用程序中显示HTML的有效方法。

但是有一个障碍:Web浏览器控件 - 默认情况下 - 永远停留在IE 7渲染模式。尽管我们现在已经升级到IE 11和一个合理的HTML5兼容浏览器,但Web浏览器控件总是默认使用IE 7渲染引擎。这是因为ActiveX控件的原始版本使用此模式并且为了向后兼容性,Control继续这个过时且非常HTML5不友好的默认值。

无论您是在WPF应用程序,WinForms应用程序或使用ActiveX控件的FoxPro应用程序中使用Web浏览器控件,这都适用。在幕后,所有这些UI平台都使用相同的COM接口,因此您仍然坚持使用相同的规则。

好消息是有几种方法可以覆盖默认的渲染行为:

  • 使用IE X-UA-CompatibleMeta标头
  • 使用应用特定的FEATURE_BROWSER_EMULATION注册表项

但首先让我们更加图形化地看待问题。

渲染挑战

为了看看我在说什么,这里有两个屏幕截图渲染一个HTML5页面,其中包括一些CSS3功能 - 圆角和边框阴影 一个使用Internet Explorer作为独立浏览器,一个使用包含Web浏览器控件的简单WPF表单。

完整的IE浏览器:

完整的Web浏览器渲染

WPF格式的Web浏览器控件:

WebBrowserControlWpfForm

完整的Internet Explorer页面正确显示HTML - 您会看到显示的圆角和阴影。显然后者在WPF应用程序中使用Web浏览器控件进行渲染有点缺乏。不仅缺少新的CSS功能,而且页面也在Internet Explorer的怪癖模式下呈现,因此默认情况下所有边距,填充等行为都不同,即使在此页面上应用了CSS重置。但是默认的IE 7模式无法识别许多这些设置,从而导致糟糕的渲染模式。

如果您正在构建一个打算使用Web浏览器控件进行某些HTML实时预览的应用程序,那么这显然是不可取的。

使用兼容X-UA的HTML元标记

如果通过呈现自己显示的HTML页面来控制Web浏览器控件中的内容,则提供IE渲染引擎的更高版本的最简单方法是使用IE Edge模式标题。通过向Web浏览器控件中呈现的HTML文档的头部添加元标记,您可以有效地覆盖IE渲染引擎并指定要使用的IE版本(或最新版本)。

标题中使用的标记如下所示:

<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 

在完整文档中,它看起来像这样:

<!DOCTYPE html> 
<html> 
  <head> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
    ... other headers
  </head>
  <body>
    ... content
  </body>
</html>

请注意标头应该是第一个标头,以便在处理任何其他标头之前应用引擎。

在这种情况下,IE=edge使用计算机上安装的当前版本的IE。因此,如果您安装了已使用的IE 11,则安装已使用的IE 10。

您还可以指定IE的特定版本:

<meta http-equiv="X-UA-Compatible" content="IE=10" /> 

您也可以X-UA-Compatible: IE=edge从Web服务器充当原始HTTP标头,其行为与http-equiv元标头相同。

使用边缘模式标题的注意事项

为了使用元标记并使其正常工作,您需要做一些事情:

  • 您必须控制页面
    为了添加<meta>您必须控制页面的<meta>标记,以便您可以将标记添加到HTML中。如果您正在渲染不包含标记的任意HTML,那么这种方法显然不会起作用。通常,如果您生成自己的内容,标题方法会很有效。
  • 浏览器版本的报告是不正确
    <meta>标签改变了使用IE渲染引擎的行为,但它不会改变IE报告其版本的方式。如果您访问进行IE版本检查的页面,您会发现它仍然指向IE 7(或某些自定义浏览器版本)并不能反映当前的渲染模式。如果您正在运行可能依赖浏览器嗅探的脚本代码,则可能会出现问题。我最近遇到了Ace编辑器,它有几个奇怪的地方,它使用浏览器嗅探来处理剪贴板,而且代码不起作用。这可能是一个边缘(哈哈)的情况,但请注意,这可能成为一个问题。

通过注册表进行修改

影响Web浏览器控件版本的另一种可能更强大的方法是使用FEATURE_BROWSER_EMULATION。从IE 8开始,Microsoft引入了一些注册表项,用于在Web浏览器控件嵌入到其他应用程序中时控制浏览器行为。这些注册表值由系统上的许多应用程序使用。

实际上,您可以使用可执行文件的名称指定注册表,并指定要加载的IE版本。数字指定为11000,10000,9000,8000和7000.可以为当前用户(HKCU)指定密钥,也可以为所有用户(HKLM)指定全局密钥。

这是我在HKCU密钥中的含义:

请注意,一些大型应用程序(如Visual Studio和Outlook)使用这些覆盖,在HKLM密钥中,您还可以找到Skype SnagIt,Fiddler,SourceTree,1Password和Windows帮助查看器等应用程序。因此,这个功能实际上被广泛的流行软件使用。

FEATURE_BROWSER模拟的注册表键位置

您可以在注册表中指定以下键:

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

HKCU密钥是设置这些值的最佳位置,因为只有一个密钥且可以在没有管理员权限的情况下设置,但您也可以在HKLM的机器级别设置这些密钥:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION

或者对于64位机器上的32位应用程序:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

密钥名称

键名是应用程序的EXE名称,如:

  • OUTLOOK.EXE
  • MarkdownMonster.exe

该值指定IE版本如下:

将此键设置为的值(取自此处的 MSDN )为十进制值:

11001(0x2AF9):Internet Explorer 11

11000(0x2AF8):Internet Explorer 11

10001(0x2AF7):Internet Explorer 10

10000(0x2710):Internet Explorer 10.

9999(0x270F):Internet Explorer 9

9000(0x2328):Internet Explorer 9

8888(0x22B8):网页以IE8标准模式显示

8000(0x1F40):包含基于标准的网页!以IE8模式显示。

7000(0x1B58):包含基于标准的网页!以IE7标准模式显示。它是默认模式。

通过设置这些密钥,您的应用程序可以轻松地在计算机上使用最新的Internet Explorer版本。不幸的是,似乎没有关键字表示使用已安装的最新版本 - 不幸的是,您必须具体了解该版本。鉴于Windows 7及更高版本可以运行IE 11,我要求用户使用IE 11,如果我想使用HTML5和更高级的CSS功能,如Flexbox,但如果您的内容更简单,您可能可以使用IE 10或甚至是IE 9。

不要忘记为主机环境添加密钥

如上所述,您必须指定您正在运行的EXE的名称作为注册表中的键。

如果您正在使用Visual Studio或Visual FoxPro等开发环境来调试应用程序,请记住,在调试时运行的主EXE 可能不是您正在构建的最终EXE。因此,在设置了注册表项后,您的调试体验可能仍然无法在Web浏览器控件中看到增强的呈现功能,因为您实际上并未运行最终的EXE。

问题是,当您在这些环境中进行调试时,您正在运行调试主机,并且为了使其正确呈现,您可能还必须拥有主机FEATURE_BROWSER_EMULATION

对于Visual Studio,这将yourapp.vshost.exe是调试主机。对于Visual FoxPro,你会想要的vfp9.exe。只需将这些密钥与您用于实际应用程序的密钥一起添加到注册表中。

应用程序的注册表项安装

重要的是要记住上面的注册表设置是针对每个应用程序进行的,因此很可能这是您想要使用安装程序设置的内容。我让安装程序在安装过程中将值写入注册表,这也会在卸载时删除密钥。

我个人总是喜欢使用HKCU密钥为每个用户设置这个值,该密钥适用于一个地方的32位和64位应用程序。

如果您在HKLM上为所有用户全局设置密钥,请记住32位和64位设置需要在注册表中进行单独设置。因此,如果您要创建安装程序,则很可能希望在应用程序中预先设置两个密钥。

安装

 

以下是.NET代码,但它应该让您了解如何轻松创建密钥:

public static void EnsureBrowserEmulationEnabled(string exename = "MarkdownMonster.exe", bool uninstall = false)
{

    try
    {
        using (
            var rk = Registry.CurrentUser.OpenSubKey(
                    @"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true)
        )
        {
            if (!uninstall)
            {
                dynamic value = rk.GetValue(exename);
                if (value == null)
                    rk.SetValue(exename, (uint)11001, RegistryValueKind.DWord);
            }
            else
                rk.DeleteValue(exename);
        }
    }
    catch
    {
    }
}

摘要

如果Web浏览器控件只是原样使用本机Internet Explorer引擎会很好,但正如您在本文中看到的那样,遗憾的是并非如此,您必须强制使用浏览器。如果您可以控制在Web浏览器控件中呈现的文档,则可以X-UA-Compatible在页面中使用标题。否则你必须使用注册表修改FEATURE_BROWSER_EMULATION

就我个人而言,我已经使用了所有使用Web浏览器控件的应用程序的注册表修改,因为我的应用程序倾向于从各种不同的来源呈现HTML - 本地生成的内容,以及用于预览的Web加载页面,有时甚至动态注入内容。最好为所有内容强制使用最新的IE版本,而不是忘记您可能需要为您可能显示的其他非应用程序内容定制标题(更新通知,注册表单,通知等)。

目前,大多数机器都将运行IE 10或11,因此与以前相比,浏览器行为不同的问题要少得多。

THE END
分享
二维码
< <上一篇
下一篇>>