网页在 IE、Chrome 和 Firefox 中有效,但在使用 .NET WebBrowser 控件时无效
Webpage works in IE, Chrome and Firefox, but not when using the .NET WebBrowser control
我在 Visual Studio 2010 年使用 WebBrowser 控件并尝试显示页面:http://lk21.org.
那个网页里面加载了很多脚本,如果我用火狐Chrome和最新版本的IE浏览器打开它就可以正常工作
我的问题是,当我尝试使用 WebBrowser 组件导航到该页面时,为什么它显示 "Bad Request"?
看看这个:
更新:
使用 Visual Vincent 的回答,页面加载得很好。
但是网站上的flash视频(或者我觉得是类似flash的东西)无法播放。请参阅下图中的比较。
奇怪的是,如果我打开 YouTube,Flash 效果很好。经过一番研究,它似乎是由其他原因引起的。知道如何解决吗?
Internet Explorer - 工作正常:
WebBrowser 控件 - 由于某种原因视频卡住无法播放:
这可能与WebBrowser
控件默认使用IE 7的文档模拟模式有关,这意味着所有页面都使用Internet Explorer 7引擎处理。由于该版本太旧,如今大多数网站都与其不兼容,这会影响您访问该页面时的功能。
您可以通过在 HKEY_LOCAL_MACHINE
配置单元或 HKEY_CURRENT_USER
的注册表项 Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
中为您的应用程序添加一个值来更改此行为。这样做是在强制您的应用程序使用 特定 版本的 IE 引擎。
我写了一个 class 可以帮助你:
'A class for changing the WebBrowser control's document emulation.
'Written by Visual Vincent, 2017.
Imports Microsoft.Win32
Imports System.Security
Imports System.Windows.Forms
Public NotInheritable Class InternetExplorer
Private Sub New()
End Sub
Public Const InternetExplorerRootKey As String = "Software\Microsoft\Internet Explorer"
Public Const BrowserEmulationKey As String = InternetExplorerRootKey & "\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION"
Public Const ActiveXObjectCachingKey As String = InternetExplorerRootKey & "\MAIN\FeatureControl\FEATURE_OBJECT_CACHING"
Private Shared ReadOnly WebBrowserInstance As New WebBrowser 'Used to get the current IE version in a .NET-friendly manner.
Public Enum BrowserEmulation As Integer
IE7 = 7000
IE8 = 8000
IE8Standards = 8888
IE9 = 9000
IE9Standards = 9999
IE10 = 10000
IE10Standards = 10001
IE11 = 11000
IE11Edge = 11001
End Enum
Public Shared Sub SetLatestBrowserEmulation(ByVal Root As RegistryRoot)
Dim Emulation As BrowserEmulation = BrowserEmulation.IE7
Select Case WebBrowserInstance.Version.Major
Case Is >= 11 : Emulation = BrowserEmulation.IE11Edge
Case 10 : Emulation = BrowserEmulation.IE10Standards
Case 9 : Emulation = BrowserEmulation.IE9Standards
Case 8 : Emulation = BrowserEmulation.IE8Standards
End Select
InternetExplorer.SetBrowserEmulation(Root, Emulation)
End Sub
Public Shared Sub SetBrowserEmulation(ByVal Root As RegistryRoot, ByVal Emulation As BrowserEmulation)
Using RootKey As RegistryKey = Root.Root
Dim EmulationKey As RegistryKey = RootKey.OpenSubKey(BrowserEmulationKey, True)
If EmulationKey Is Nothing Then EmulationKey = RootKey.CreateSubKey(BrowserEmulationKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
Using EmulationKey
EmulationKey.SetValue(Process.GetCurrentProcess().ProcessName & ".exe", CType(Emulation, Integer), RegistryValueKind.DWord)
End Using
End Using
End Sub
Public Shared Sub SetActiveXObjectCaching(ByVal Root As RegistryRoot, ByVal Enabled As Boolean)
Using RootKey As RegistryKey = Root.Root
Dim ObjectCachingKey As RegistryKey = RootKey.OpenSubKey(ActiveXObjectCachingKey, True)
If ObjectCachingKey Is Nothing Then ObjectCachingKey = RootKey.CreateSubKey(ActiveXObjectCachingKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
Using ObjectCachingKey
ObjectCachingKey.SetValue(Process.GetCurrentProcess().ProcessName & ".exe", CType(If(Enabled, 1, 0), Integer), RegistryValueKind.DWord)
End Using
End Using
End Sub
Public NotInheritable Class RegistryRoot
Private _root As RegistryKey
Public ReadOnly Property Root As RegistryKey
Get
Return _root
End Get
End Property
Public Shared ReadOnly Property HKEY_LOCAL_MACHINE As RegistryRoot
Get
Return New RegistryRoot(Registry.LocalMachine)
End Get
End Property
Public Shared ReadOnly Property HKEY_CURRENT_USER As RegistryRoot
Get
Return New RegistryRoot(Registry.CurrentUser)
End Get
End Property
Private Sub New(ByVal Root As RegistryKey)
Me._root = Root
End Sub
End Class
End Class
要使用它,请在应用程序的 Startup
事件中放入 其中的一行 :
InternetExplorer.SetLatestBrowserEmulation(InternetExplorer.RegistryRoot.HKEY_LOCAL_MACHINE)
'HKEY_CURRENT_USER is recommended if you do not want to run your application with administrative privileges.
InternetExplorer.SetLatestBrowserEmulation(InternetExplorer.RegistryRoot.HKEY_CURRENT_USER)
(注意: 使用 HKEY_LOCAL_MACHINE
root 需要管理权限)
InternetExplorer.SetLatestBrowserEmulation()
方法将在指定的注册表根目录中为您的应用程序设置浏览器仿真为 最新安装版本 Internet Explorer。
但是使用InternetExplorer.SetBrowserEmulation()
方法你可以手动控制它应该使用哪个IE版本(不推荐!)。
阅读更多:
编辑
我似乎根本无法进入那个网站,但据我所读there have been problems with Flash hosted in the WebBrowser control。
您可以尝试禁用 ActiveX Object Caching feature,这显然会导致 Flash 控件出现一些问题。
我更新了上面的InternetExplorer
class。 Copy-paste 它,然后将此行添加到应用程序的启动事件中:
InternetExplorer.SetActiveXObjectCaching(InternetExplorer.RegistryRoot.HKEY_CURRENT_USER, False)
如果还是不行,恐怕你运气不好。我没能找到任何其他有用的东西。
基于@Visual Vincent的回答,这里我做了一个重做的解决方案:
1 - IEBrowserEmulationMode 枚举:
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Specifies a Internet Explorer browser emulation mode.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
Public Enum IEBrowserEmulationMode As Integer
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.
''' </summary>
IE7 = 7000
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.
''' </summary>
IE8 = 8000
''' <summary>
''' Webpages are displayed in IE8 Standards mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE8Standards = 8888
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.
''' </summary>
IE9 = 9000
''' <summary>
''' Webpages are displayed in IE9 Standards mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE9Standards = 9999
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
''' </summary>
IE10 = 10000
''' <summary>
''' Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
''' </summary>
IE10Standards = 10001
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode.
''' </summary>
IE11 = 11000
''' <summary>
''' Webpages are displayed in IE11 edge mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE11Edge = 11001
End Enum
2 - RegistryScope 枚举。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Specifies a registry scope (a root key).
''' </summary>
''' ----------------------------------------------------------------------------------------------------
Public Enum RegistryScope As Integer
''' <summary>
''' This refers to the HKEY_LOCAL_MACHINE (or HKLM) registry root key.
''' <para></para>
''' Configuration changes made on the subkeys of this root key will affect all users.
''' </summary>
Machine = 0
''' <summary>
''' This refers to the HKEY_CURRENT_USER (or HKCU) registry root key.
''' <para></para>
''' Configuration changes made on the subkeys of this root key will affect only the current user.
''' </summary>
CurrentUser = 1
End Enum
3 - BrowserEmulationMode 属性,获取或设置当前应用程序的 IE 浏览器仿真模式。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets or sets the Internet Explorer browser emulation mode for the current application.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example to get, set and verify the IE browser emulation mode for the current process.
''' <code>
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = BrowserEmulationMode(scope)
''' BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
''' newMode = BrowserEmulationMode(scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <value>
''' The Internet Explorer browser emulation mode.
''' </value>
''' ----------------------------------------------------------------------------------------------------
Public Shared Property BrowserEmulationMode(ByVal scope As RegistryScope) As IEBrowserEmulationMode
<DebuggerStepThrough>
Get
Return GetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope)
End Get
<DebuggerStepThrough>
Set(value As IEBrowserEmulationMode)
SetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope, value)
End Set
End Property
3 - GetIEBrowserEmulationMode 函数和 SetIEBrowserEmulationMode 方法,用于获取或设置外部应用程序的 IE 浏览器仿真模式。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As String = Process.GetCurrentProcess().ProcessName
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
'''
''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="processName">
''' The process name (eg. 'cmd.exe').
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting <see cref="IEBrowserEmulationMode"/>.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope) As IEBrowserEmulationMode
processName = Path.GetFileNameWithoutExtension(processName)
Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
subKey As RegistryKey = rootKey.CreateSubKey("Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadSubTree)
Dim value As Integer =
CInt(subKey.GetValue(String.Format("{0}.exe", processName), 0, RegistryValueOptions.None))
' If no browser emulation mode is retrieved from registry, then return default version for WebBrowser control.
If (value = 0) Then
Return IEBrowserEmulationMode.IE7
End If
If [Enum].IsDefined(GetType(IEBrowserEmulationMode), value) Then
Return DirectCast(value, IEBrowserEmulationMode)
Else
Throw New NotSupportedException(String.Format("Undefined browser emulation value retrieved from registry: '{0}'", value))
End If
End Using
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim p As Process = Process.GetCurrentProcess()
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(p, scope)
'''
''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="p">
''' The process.
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting <see cref="IEBrowserEmulationMode"/>.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope) As IEBrowserEmulationMode
Return GetIEBrowserEmulationMode(p.ProcessName, scope)
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Sets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As String = Process.GetCurrentProcess().ProcessName
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = GetIEBrowserEmulationMode(processName, scope)
''' SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
''' newMode = GetIEBrowserEmulationMode(processName, scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="processName">
''' The process name (eg. 'cmd.exe').
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
'''
''' <param name="mode">
''' The Internet Explorer browser emulation mode to set.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub SetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
processName = Path.GetFileNameWithoutExtension(processName)
Dim currentIEBrowserEmulationMode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
If (currentIEBrowserEmulationMode = mode) Then
Exit Sub
End If
Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
subKey As RegistryKey = rootKey.CreateSubKey(
"Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadWriteSubTree)
subKey.SetValue(String.Format("{0}.exe", processName),
DirectCast(mode, Integer), RegistryValueKind.DWord)
End Using
End Sub
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Sets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As Process = Process.GetCurrentProcess()
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = GetIEBrowserEmulationMode(p, scope)
''' SetIEBrowserEmulationMode(p, scope, IEBrowserEmulationMode.IE11Edge)
''' newMode = GetIEBrowserEmulationMode(p, scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="p">
''' The process.
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
'''
''' <param name="mode">
''' The Internet Explorer browser emulation mode to set.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub SetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
SetIEBrowserEmulationMode(p.ProcessName, scope, mode)
End Sub
获取、设置和验证当前进程的IE浏览器仿真模式的使用示例:
Dim scope As RegistryScope = RegistryScope.CurrentUser
Dim oldMode As IEBrowserEmulationMode
Dim newMode As IEBrowserEmulationMode
oldMode = BrowserEmulationMode(scope)
BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
newMode = BrowserEmulationMode(scope)
Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
Dim f As New Form() With {.Size = New Size(1280, 720)}
Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
f.Controls.Add(wb)
f.Show()
wb.Navigate("http://www.whatversion.net/browser/")
获取、设置和验证特定进程的 IE 浏览器仿真模式的使用示例:
Dim processName As String = Process.GetCurrentProcess().ProcessName
Dim scope As RegistryScope = RegistryScope.CurrentUser
Dim oldMode As IEBrowserEmulationMode
Dim newMode As IEBrowserEmulationMode
oldMode = GetIEBrowserEmulationMode(processName, scope)
SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
newMode = GetIEBrowserEmulationMode(processName, scope)
Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
Dim f As New Form() With {.Size = New Size(1280, 720)}
Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
f.Controls.Add(wb)
f.Show()
wb.Navigate("http://www.whatversion.net/browser/")
我在 Visual Studio 2010 年使用 WebBrowser 控件并尝试显示页面:http://lk21.org.
那个网页里面加载了很多脚本,如果我用火狐Chrome和最新版本的IE浏览器打开它就可以正常工作
我的问题是,当我尝试使用 WebBrowser 组件导航到该页面时,为什么它显示 "Bad Request"?
看看这个:
更新:
使用 Visual Vincent 的回答,页面加载得很好。
但是网站上的flash视频(或者我觉得是类似flash的东西)无法播放。请参阅下图中的比较。
奇怪的是,如果我打开 YouTube,Flash 效果很好。经过一番研究,它似乎是由其他原因引起的。知道如何解决吗?
Internet Explorer - 工作正常:
WebBrowser 控件 - 由于某种原因视频卡住无法播放:
这可能与WebBrowser
控件默认使用IE 7的文档模拟模式有关,这意味着所有页面都使用Internet Explorer 7引擎处理。由于该版本太旧,如今大多数网站都与其不兼容,这会影响您访问该页面时的功能。
您可以通过在 HKEY_LOCAL_MACHINE
配置单元或 HKEY_CURRENT_USER
的注册表项 Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
中为您的应用程序添加一个值来更改此行为。这样做是在强制您的应用程序使用 特定 版本的 IE 引擎。
我写了一个 class 可以帮助你:
'A class for changing the WebBrowser control's document emulation.
'Written by Visual Vincent, 2017.
Imports Microsoft.Win32
Imports System.Security
Imports System.Windows.Forms
Public NotInheritable Class InternetExplorer
Private Sub New()
End Sub
Public Const InternetExplorerRootKey As String = "Software\Microsoft\Internet Explorer"
Public Const BrowserEmulationKey As String = InternetExplorerRootKey & "\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION"
Public Const ActiveXObjectCachingKey As String = InternetExplorerRootKey & "\MAIN\FeatureControl\FEATURE_OBJECT_CACHING"
Private Shared ReadOnly WebBrowserInstance As New WebBrowser 'Used to get the current IE version in a .NET-friendly manner.
Public Enum BrowserEmulation As Integer
IE7 = 7000
IE8 = 8000
IE8Standards = 8888
IE9 = 9000
IE9Standards = 9999
IE10 = 10000
IE10Standards = 10001
IE11 = 11000
IE11Edge = 11001
End Enum
Public Shared Sub SetLatestBrowserEmulation(ByVal Root As RegistryRoot)
Dim Emulation As BrowserEmulation = BrowserEmulation.IE7
Select Case WebBrowserInstance.Version.Major
Case Is >= 11 : Emulation = BrowserEmulation.IE11Edge
Case 10 : Emulation = BrowserEmulation.IE10Standards
Case 9 : Emulation = BrowserEmulation.IE9Standards
Case 8 : Emulation = BrowserEmulation.IE8Standards
End Select
InternetExplorer.SetBrowserEmulation(Root, Emulation)
End Sub
Public Shared Sub SetBrowserEmulation(ByVal Root As RegistryRoot, ByVal Emulation As BrowserEmulation)
Using RootKey As RegistryKey = Root.Root
Dim EmulationKey As RegistryKey = RootKey.OpenSubKey(BrowserEmulationKey, True)
If EmulationKey Is Nothing Then EmulationKey = RootKey.CreateSubKey(BrowserEmulationKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
Using EmulationKey
EmulationKey.SetValue(Process.GetCurrentProcess().ProcessName & ".exe", CType(Emulation, Integer), RegistryValueKind.DWord)
End Using
End Using
End Sub
Public Shared Sub SetActiveXObjectCaching(ByVal Root As RegistryRoot, ByVal Enabled As Boolean)
Using RootKey As RegistryKey = Root.Root
Dim ObjectCachingKey As RegistryKey = RootKey.OpenSubKey(ActiveXObjectCachingKey, True)
If ObjectCachingKey Is Nothing Then ObjectCachingKey = RootKey.CreateSubKey(ActiveXObjectCachingKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
Using ObjectCachingKey
ObjectCachingKey.SetValue(Process.GetCurrentProcess().ProcessName & ".exe", CType(If(Enabled, 1, 0), Integer), RegistryValueKind.DWord)
End Using
End Using
End Sub
Public NotInheritable Class RegistryRoot
Private _root As RegistryKey
Public ReadOnly Property Root As RegistryKey
Get
Return _root
End Get
End Property
Public Shared ReadOnly Property HKEY_LOCAL_MACHINE As RegistryRoot
Get
Return New RegistryRoot(Registry.LocalMachine)
End Get
End Property
Public Shared ReadOnly Property HKEY_CURRENT_USER As RegistryRoot
Get
Return New RegistryRoot(Registry.CurrentUser)
End Get
End Property
Private Sub New(ByVal Root As RegistryKey)
Me._root = Root
End Sub
End Class
End Class
要使用它,请在应用程序的 Startup
事件中放入 其中的一行 :
InternetExplorer.SetLatestBrowserEmulation(InternetExplorer.RegistryRoot.HKEY_LOCAL_MACHINE)
'HKEY_CURRENT_USER is recommended if you do not want to run your application with administrative privileges.
InternetExplorer.SetLatestBrowserEmulation(InternetExplorer.RegistryRoot.HKEY_CURRENT_USER)
(注意: 使用 HKEY_LOCAL_MACHINE
root 需要管理权限)
InternetExplorer.SetLatestBrowserEmulation()
方法将在指定的注册表根目录中为您的应用程序设置浏览器仿真为 最新安装版本 Internet Explorer。
但是使用InternetExplorer.SetBrowserEmulation()
方法你可以手动控制它应该使用哪个IE版本(不推荐!)。
阅读更多:
编辑
我似乎根本无法进入那个网站,但据我所读there have been problems with Flash hosted in the WebBrowser control。
您可以尝试禁用 ActiveX Object Caching feature,这显然会导致 Flash 控件出现一些问题。
我更新了上面的InternetExplorer
class。 Copy-paste 它,然后将此行添加到应用程序的启动事件中:
InternetExplorer.SetActiveXObjectCaching(InternetExplorer.RegistryRoot.HKEY_CURRENT_USER, False)
如果还是不行,恐怕你运气不好。我没能找到任何其他有用的东西。
基于@Visual Vincent的回答,这里我做了一个重做的解决方案:
1 - IEBrowserEmulationMode 枚举:
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Specifies a Internet Explorer browser emulation mode.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
Public Enum IEBrowserEmulationMode As Integer
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.
''' </summary>
IE7 = 7000
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.
''' </summary>
IE8 = 8000
''' <summary>
''' Webpages are displayed in IE8 Standards mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE8Standards = 8888
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.
''' </summary>
IE9 = 9000
''' <summary>
''' Webpages are displayed in IE9 Standards mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE9Standards = 9999
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
''' </summary>
IE10 = 10000
''' <summary>
''' Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
''' </summary>
IE10Standards = 10001
''' <summary>
''' Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode.
''' </summary>
IE11 = 11000
''' <summary>
''' Webpages are displayed in IE11 edge mode, regardless of the declared !DOCTYPE directive.
''' <para></para>
''' Failing to declare a !DOCTYPE directive causes the page to load in Quirks.
''' </summary>
IE11Edge = 11001
End Enum
2 - RegistryScope 枚举。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Specifies a registry scope (a root key).
''' </summary>
''' ----------------------------------------------------------------------------------------------------
Public Enum RegistryScope As Integer
''' <summary>
''' This refers to the HKEY_LOCAL_MACHINE (or HKLM) registry root key.
''' <para></para>
''' Configuration changes made on the subkeys of this root key will affect all users.
''' </summary>
Machine = 0
''' <summary>
''' This refers to the HKEY_CURRENT_USER (or HKCU) registry root key.
''' <para></para>
''' Configuration changes made on the subkeys of this root key will affect only the current user.
''' </summary>
CurrentUser = 1
End Enum
3 - BrowserEmulationMode 属性,获取或设置当前应用程序的 IE 浏览器仿真模式。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets or sets the Internet Explorer browser emulation mode for the current application.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example to get, set and verify the IE browser emulation mode for the current process.
''' <code>
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = BrowserEmulationMode(scope)
''' BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
''' newMode = BrowserEmulationMode(scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <value>
''' The Internet Explorer browser emulation mode.
''' </value>
''' ----------------------------------------------------------------------------------------------------
Public Shared Property BrowserEmulationMode(ByVal scope As RegistryScope) As IEBrowserEmulationMode
<DebuggerStepThrough>
Get
Return GetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope)
End Get
<DebuggerStepThrough>
Set(value As IEBrowserEmulationMode)
SetIEBrowserEmulationMode(Process.GetCurrentProcess().ProcessName, scope, value)
End Set
End Property
3 - GetIEBrowserEmulationMode 函数和 SetIEBrowserEmulationMode 方法,用于获取或设置外部应用程序的 IE 浏览器仿真模式。
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As String = Process.GetCurrentProcess().ProcessName
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
'''
''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="processName">
''' The process name (eg. 'cmd.exe').
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting <see cref="IEBrowserEmulationMode"/>.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope) As IEBrowserEmulationMode
processName = Path.GetFileNameWithoutExtension(processName)
Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
subKey As RegistryKey = rootKey.CreateSubKey("Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadSubTree)
Dim value As Integer =
CInt(subKey.GetValue(String.Format("{0}.exe", processName), 0, RegistryValueOptions.None))
' If no browser emulation mode is retrieved from registry, then return default version for WebBrowser control.
If (value = 0) Then
Return IEBrowserEmulationMode.IE7
End If
If [Enum].IsDefined(GetType(IEBrowserEmulationMode), value) Then
Return DirectCast(value, IEBrowserEmulationMode)
Else
Throw New NotSupportedException(String.Format("Undefined browser emulation value retrieved from registry: '{0}'", value))
End If
End Using
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim p As Process = Process.GetCurrentProcess()
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim mode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(p, scope)
'''
''' Console.WriteLine(String.Format("Mode: {0} ({1})", mode, CStr(mode)))
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="p">
''' The process.
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting <see cref="IEBrowserEmulationMode"/>.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope) As IEBrowserEmulationMode
Return GetIEBrowserEmulationMode(p.ProcessName, scope)
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Sets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As String = Process.GetCurrentProcess().ProcessName
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = GetIEBrowserEmulationMode(processName, scope)
''' SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
''' newMode = GetIEBrowserEmulationMode(processName, scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="processName">
''' The process name (eg. 'cmd.exe').
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
'''
''' <param name="mode">
''' The Internet Explorer browser emulation mode to set.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub SetIEBrowserEmulationMode(ByVal processName As String, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
processName = Path.GetFileNameWithoutExtension(processName)
Dim currentIEBrowserEmulationMode As IEBrowserEmulationMode = GetIEBrowserEmulationMode(processName, scope)
If (currentIEBrowserEmulationMode = mode) Then
Exit Sub
End If
Using rootKey As RegistryKey = If(scope = RegistryScope.CurrentUser,
RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default),
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default)),
subKey As RegistryKey = rootKey.CreateSubKey(
"Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadWriteSubTree)
subKey.SetValue(String.Format("{0}.exe", processName),
DirectCast(mode, Integer), RegistryValueKind.DWord)
End Using
End Sub
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Sets the Internet Explorer browser emulation mode for the specified process.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <seealso href="https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)"/>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim processName As Process = Process.GetCurrentProcess()
''' Dim scope As RegistryScope = RegistryScope.CurrentUser
''' Dim oldMode As IEBrowserEmulationMode
''' Dim newMode As IEBrowserEmulationMode
'''
''' oldMode = GetIEBrowserEmulationMode(p, scope)
''' SetIEBrowserEmulationMode(p, scope, IEBrowserEmulationMode.IE11Edge)
''' newMode = GetIEBrowserEmulationMode(p, scope)
'''
''' Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
''' Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
'''
''' Dim f As New Form() With {.Size = New Size(1280, 720)}
''' Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
''' f.Controls.Add(wb)
''' f.Show()
''' wb.Navigate("http://www.whatversion.net/browser/")
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="p">
''' The process.
''' </param>
'''
''' <param name="scope">
''' The registry scope.
''' </param>
'''
''' <param name="mode">
''' The Internet Explorer browser emulation mode to set.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="NotSupportedException">
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub SetIEBrowserEmulationMode(ByVal p As Process, ByVal scope As RegistryScope, ByVal mode As IEBrowserEmulationMode)
SetIEBrowserEmulationMode(p.ProcessName, scope, mode)
End Sub
获取、设置和验证当前进程的IE浏览器仿真模式的使用示例:
Dim scope As RegistryScope = RegistryScope.CurrentUser
Dim oldMode As IEBrowserEmulationMode
Dim newMode As IEBrowserEmulationMode
oldMode = BrowserEmulationMode(scope)
BrowserEmulationMode(scope) = IEBrowserEmulationMode.IE11Edge
newMode = BrowserEmulationMode(scope)
Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
Dim f As New Form() With {.Size = New Size(1280, 720)}
Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
f.Controls.Add(wb)
f.Show()
wb.Navigate("http://www.whatversion.net/browser/")
获取、设置和验证特定进程的 IE 浏览器仿真模式的使用示例:
Dim processName As String = Process.GetCurrentProcess().ProcessName
Dim scope As RegistryScope = RegistryScope.CurrentUser
Dim oldMode As IEBrowserEmulationMode
Dim newMode As IEBrowserEmulationMode
oldMode = GetIEBrowserEmulationMode(processName, scope)
SetIEBrowserEmulationMode(processName, scope, IEBrowserEmulationMode.IE11Edge)
newMode = GetIEBrowserEmulationMode(processName, scope)
Console.WriteLine(String.Format("Old Mode: {0} ({1})", oldMode, CStr(oldMode)))
Console.WriteLine(String.Format("New Mode: {0} ({1})", newMode, CStr(newMode)))
Dim f As New Form() With {.Size = New Size(1280, 720)}
Dim wb As New WebBrowser With {.Dock = DockStyle.Fill}
f.Controls.Add(wb)
f.Show()
wb.Navigate("http://www.whatversion.net/browser/")