Web浏览器控件仿真问题(FEATURE_BROWSER_EMULATION)

4
使用VS2013创建了一个非常简单的Web浏览器控件应用程序,可以导航到 http://demos.dojotoolkit.org/demos/calendar/demo.html
当在注册表中未设置FEATURE_BROWSER_EMULATION时,该应用程序可以正常运行。将应用程序添加到此注册表键(在HKLM下)后,它在IE9仿真模式下工作,但在IE10和IE11值下失败(我使用的是IE11)。
例如:
FEATURE_BROWSER_EMULATION

myApp=9999 - works

myApp=10001 - doesn't work

无法工作 = 月份日期选择器不起作用。有什么建议可以解决问题吗?

谢谢, Guy

2个回答

20
以下是我的C# WebBrowser 游乐场应用程序,可以与您的URL (http://demos.dojotoolkit.org/demos/calendar/demo.html) 很好地配合使用。

我相信禁用FEATURE_NINPUT_LEGACY_MODE 是做出改变的原因。我还启用了其他一些设置。它还展示了如何使用 HKEY_CURRENT_USER 而不是 HKLM,这样应用程序就不需要管理员权限。

using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WebBrowserApp
{
    public partial class MainForm : Form
    {
        const int POLL_DELAY = 250;
        WebBrowser _webBrowser;

        // set WebBrowser features, more info: https://dev59.com/VmMl5IYBdhLWcg3wgnWl#18333982
        static void SetWebBrowserFeatures()
        {
            // don't change the registry if running in-proc inside Visual Studio
            if (LicenseManager.UsageMode != LicenseUsageMode.Runtime)
                return;

            var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);

            var featureControlRegKey = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\";

            Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION",
                appName, GetBrowserEmulationMode(), RegistryValueKind.DWord);

            // enable the features which are "On" for the full Internet Explorer browser

            Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION",
                appName, 1, RegistryValueKind.DWord);

            Registry.SetValue(featureControlRegKey + "FEATURE_AJAX_CONNECTIONEVENTS",
                appName, 1, RegistryValueKind.DWord);

            Registry.SetValue(featureControlRegKey + "FEATURE_GPU_RENDERING",
                appName, 1, RegistryValueKind.DWord);

            Registry.SetValue(featureControlRegKey + "FEATURE_WEBOC_DOCUMENT_ZOOM",
                appName, 1, RegistryValueKind.DWord);

            Registry.SetValue(featureControlRegKey + "FEATURE_NINPUT_LEGACYMODE",
                appName, 0, RegistryValueKind.DWord);
        }

        static UInt32 GetBrowserEmulationMode()
        {
            int browserVersion = 0;
            using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer",
                RegistryKeyPermissionCheck.ReadSubTree,
                System.Security.AccessControl.RegistryRights.QueryValues))
            {
                var version = ieKey.GetValue("svcVersion");
                if (null == version)
                {
                    version = ieKey.GetValue("Version");
                    if (null == version)
                        throw new ApplicationException("Microsoft Internet Explorer is required!");
                }
                int.TryParse(version.ToString().Split('.')[0], out browserVersion);
            }

            if (browserVersion < 7)
            {
                throw new ApplicationException("Unsupported version of Microsoft Internet Explorer!");
            }

            UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. 

            switch (browserVersion)
            {
                case 7:
                    mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. 
                    break;
                case 8:
                    mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. 
                    break;
                case 9:
                    mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.                    
                    break;
                case 10:
                    mode = 10000; // Internet Explorer 10.
                    break;
            }

            return mode;
        }

        // static constructor, runs first
        static MainForm()
        {
            SetWebBrowserFeatures();
        }

        public MainForm()
        {
            InitializeComponent();

            _webBrowser = new WebBrowser() { Dock = DockStyle.Fill };
            this.Controls.Add(_webBrowser);

            this.Size = new System.Drawing.Size(800, 600);
            this.Load += MainForm_Load;
        }

        // start the task
        async void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                dynamic document = await LoadDynamicPage("http://demos.dojotoolkit.org/demos/calendar/demo.html",
                    CancellationToken.None);

                MessageBox.Show(new { document.documentMode, document.compatMode }.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // navigate and download 
        async Task<object> LoadDynamicPage(string url, CancellationToken token)
        {
            // navigate and await DocumentCompleted
            var tcs = new TaskCompletionSource<bool>();
            WebBrowserDocumentCompletedEventHandler handler = (s, arg) =>
                tcs.TrySetResult(true);

            using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false))
            {
                this._webBrowser.DocumentCompleted += handler;
                try
                {
                    this._webBrowser.Navigate(url);
                    await tcs.Task; // wait for DocumentCompleted
                }
                finally
                {
                    this._webBrowser.DocumentCompleted -= handler;
                }
            }

            // get the root element
            var documentElement = this._webBrowser.Document.GetElementsByTagName("html")[0];

            // poll the current HTML for changes asynchronosly
            var html = documentElement.OuterHtml;
            while (true)
            {
                // wait asynchronously, this will throw if cancellation requested
                await Task.Delay(POLL_DELAY, token);

                // continue polling if the WebBrowser is still busy
                if (this._webBrowser.IsBusy)
                    continue;

                var htmlNow = documentElement.OuterHtml;
                if (html == htmlNow)
                    break; // no changes detected, end the poll loop

                html = htmlNow;
            }

            // consider the page fully rendered 
            token.ThrowIfCancellationRequested();

            return this._webBrowser.Document.DomDocument;
        }
    }
}

-1

这个方法对我有效:

yourWebBrowser.ScriptErrorsSuppressed = true;

详情请查看以下网站关于 ScriptErrorsSuppressed 的信息

摘自网站:

注意事项
将此属性设置为 false 以调试您在 WebBrowser 控件中显示的 Web 页面。当您使用控件向应用程序添加基于 Web 的控件和脚本代码时,这很有用。当您将控件用作通用浏览器时,它的用处就较小了。完成调试应用程序后,将此属性设置为 true 以禁止脚本错误。

当 ScriptErrorsSuppressed 设置为 true 时,WebBrowser 控件会隐藏所有源自基础 ActiveX 控件的对话框,而不仅仅是脚本错误。有时,您可能需要在显示诸如用于浏览器安全设置和用户登录的对话框时禁止脚本错误。在这种情况下,请将 ScriptErrorsSuppressed 设置为 false,并在 HtmlWindow.Error 事件处理程序中抑制脚本错误。有关详细信息,请参阅本主题中的代码示例。


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