一、問題解析:
今天在調試程序的時候,需要使用C#的客戶端遠程登錄一個Web頁面,用到了WebBrowser控件。但是卻發現了一件很神奇的事情:當前瀏覽器使用的內核,可以通過訪問下面這個網站獲取:http://ie.icoa.cn/,我的IE版本為IE8,在使用IE登錄頁面的時候,使用的內核是IE8,登錄該網站的截圖如下:
但是當我用WebBrowser登錄該頁面時,顯示使用的內核卻是IE7:
上圖的程序是一個測試程序,僅包含一個WebBrowser,這個程序的名稱是TestWebBrowser.exe。可以發現,雖然同為Trident內核,但在WebBrowser控件中使用的內核版本卻與IE不一樣,這讓我感到疑惑。因為我要登錄的頁面是針對IE8以上版本開發的,因此我需要嘗試讓程序內的WebBrowser以IE8的內核登錄網頁。
二、解決方法
在網上找了一些資料后,我發現可以通過下面這個辦法來解決:
第一個解決方法:
1、在開始菜單內輸入“regedit.exe”,進入注冊表編輯器
2、找到注冊表項:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
3、在右側空白區域內單擊鼠標右鍵,點擊【新建】→【DWORD(32-位)值】
4、新建的項取名為TestWebBrowser.exe,編輯值時,選擇基數“十進制”,填寫數值數據,這里填寫8888
5、這個時候再進入Debug目錄下生成好的TestWebBrowser,可以看到登錄的內核版本變成IE8了!
需要注意的是,在VS內以調試的方法進入程序,打開的程序實際上是TestWebBrowser.vshost.exe,並不能看到效果,必須要打開Debug目錄下的TestWebBrowser.exe,才能發現內核版本的改變。之前WebBrowser使用IE7內核的原因,就是.NET中的WebBrowser控件默認使用了IE7兼容性模式來瀏覽網頁。
第二種方法:(代碼實現第一種方法)
/// <summary> /// 修正WebBrowser控件的瀏覽器內核版本 /// </summary> /// <param name="processName">待修正的進程名:System.Diagnostics.Process.GetCurrentProcess().ProcessName</param> public static void FixBrowserVersionForWebBrowserControl(string processName) { try { int browserVersion, registerValue; // get the installed IE version using (var webBrowser = new System.Windows.Forms.WebBrowser()) { browserVersion = webBrowser.Version.Major; } // set the appropriate IE version if (browserVersion >= 11) registerValue = 11001; else if (browserVersion == 10) registerValue = 10001; else if (browserVersion == 9) registerValue = 9999; else if (browserVersion == 8) registerValue = 8888; else registerValue = 7000; // set the actual key using (var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true)) { if (key != null) { //key.SetValue(System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe", registerValue, Microsoft.Win32.RegistryValueKind.DWord); key.SetValue(processName + ".exe", registerValue, Microsoft.Win32.RegistryValueKind.DWord); key.Close(); } } } catch (Exception ex) { Console.WriteLine(ex); } }
三、擴展
上面這個方法依靠修改注冊表來完成WebBrowser使用內核的變更,不過光知道新建一個注冊表項並把值設置為“8888”還遠遠不夠,本着“知其然還要知其所以然”的想法,我查閱了相關的MSDN頁面:https://msdn.microsoft.com/en-us/library/ee330730%28v=vs.85%29.aspx
這個頁面的標題是:Internet Feature Controls (B..C),即互聯網功能控制,我們要找的章節是“Browser Emulation”(瀏覽器仿真)。原來自從IE8以后,在注冊表中添加了FEATURE_BROWSER_EMULATION功能,這個功能是用來定義IE默認的仿真模式。
這個功能在注冊表中的位置如下:
該注冊表項的各可能取值描述如下(原文見MSDN,純手工翻譯,如有不足之處歡迎指出)
-
7000 (0x1B58)
Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.
包含標准!DOCTYPE指令的頁面將會以IE7兼容模式打開。WebBrowser控件的默認值。
-
8000 (0x1F40)
Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8
Important In Internet Explorer 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
包含標准!DOCTYPE指令的頁面將會以IE8兼容模式打開,IE8瀏覽器的默認值。對於IE10來說,包含標准!DOCTYPE指令的頁面會以IE10兼容模式打開。
-
8888 (0x22B8)
Webpages are displayed in IE8 Standards mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
無論是否聲明!DOCTYPE指令,頁面以IE8兼容模式打開。對於未正確聲明!DOCTYPE指令的頁面,將會以怪異模式(quirks mode)加載。
-
9000 (0x2328)
Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.
Important In Internet Explorer 10, Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
IE9,包含標准!DOCTYPE指令的頁面將會以IE9兼容模式打開,IE9瀏覽器的默認值。對於IE10來說,包含標准!DOCTYPE指令的頁面會以IE10兼容模式打開。
-
9999 (0x270F)
Windows Internet Explorer 9. Webpages are displayed in IE9 Standards mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
IE9,無論是否聲明!DOCTYPE指令,頁面以IE9兼容模式打開。對於未正確聲明!DOCTYPE指令的頁面,將會以怪異模式(quirks mode)加載。
-
10000 (0x02710)
Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for Internet Explorer 10.
IE10,包含標准!DOCTYPE指令的頁面將會以IE10兼容模式打開,IE10瀏覽器的默認值。
-
10001 (0x2711)
Internet Explorer 10. Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
IE10,無論是否聲明!DOCTYPE指令,頁面以IE10兼容模式打開。
-
11001 (0x2AF9)
IE11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode. Default value for IE11.
IE11,包含標准!DOCTYPE指令的頁面將會以IE11兼容模式打開,IE11瀏覽器的默認值。
-
11000 (0x2AF8)
Internet Explorer 11. Webpages are displayed in IE11 edge mode, regardless of the declared !DOCTYPE directive. Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
IE11,無論是否聲明!DOCTYPE指令,頁面將會以IE11的edge模式打開。對於未正確聲明!DOCTYPE指令的頁面,將會以怪異模式(quirks mode)加載。