Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

vb.net - Webpage works in IE, Chrome and Firefox, but not when using the .NET WebBrowser control

I'm using the WebBrowser control in Visual Studio 2010 and trying to display the page: http://lk21.org.

Inside that webpage there are lots of scripts loaded, and it works fine if I open it through a web browser such as Firefox, Chrome, and the latest version of IE.

My question is, why does it display "Bad Request" when I tried using the WebBrowser component to navigate to that page?

Check this out:

enter image description here


UPDATE:

The page loads nicely using Visual Vincent's answer.

However the flash videos on the website (or I think it's something similar to flash) is unable to be played. See the comparison in the images below.

The strange thing is, if I open YouTube the flash works well. After a bit research, it seems to be caused by something else. Any clue how to solve it?

Internet Explorer - works fine:

enter image description here

WebBrowser control - for some reason the video is stuck and can't be played:

enter image description here

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It has probably got to do with that the WebBrowser control by default uses a document emulation mode of IE 7, meaning all pages are handled using the Internet Explorer 7 engine. Since that version is quite old most websites today are not compatible with it, which affects the functionality when you visit the page.

You can change this behaviour by adding a value for your application in the registry key SoftwareMicrosoftInternet ExplorerMAINFeatureControlFEATURE_BROWSER_EMULATION in either the HKEY_LOCAL_MACHINE hive or HKEY_CURRENT_USER. By doing so you are forcing your application to use a specific version of the IE engine.

I've written a class which will help you with this:

'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 = "SoftwareMicrosoftInternet Explorer"
    Public Const BrowserEmulationKey As String = InternetExplorerRootKey & "MAINFeatureControlFEATURE_BROWSER_EMULATION"
    Public Const ActiveXObjectCachingKey As String = InternetExplorerRootKey & "MAINFeatureControlFEATURE_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

To use it, put one of these lines in the application's Startup event:

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)

(NOTE: Using the HKEY_LOCAL_MACHINE root requires administrative privileges)

The InternetExplorer.SetLatestBrowserEmulation() method will set the browser emulation for your application, in the specified registry root, to the latest INSTALLED version of Internet Explorer.

However using the InternetExplorer.SetBrowserEmulation() method you can manually control what IE version it should use (not recommended!).

Read more:


EDIT

I seem to be unable to enter that site at all, but from what I've read there have been problems with Flash hosted in the WebBrowser control.

What you can try is to disable the ActiveX Object Caching feature, which can apparently cause some issues for Flash controls.

I updated the above InternetExplorer class. Copy-paste it, then add this line to your application's startup event:

InternetExplorer.SetActiveXObjectCaching(InternetExplorer.RegistryRoot.HKEY_CURRENT_USER, False)

If it still doesn't work then I'm afraid you're out of luck. I have not been able to find anything else that is useful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...