vb.net - webbrowser - web browser firefox c#




Página da Web funciona no IE, Chrome e Firefox, mas não ao usar o controle.NET WebBrowser (2)

Baseado na resposta do @ Visual Vincent , aqui fiz uma solução reformulada:

1 - enumeração 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 - enumeração 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 - Propriedade BrowserEmulationMode , para obter ou definir o modo de emulação do navegador IE para o aplicativo atual.

''' ----------------------------------------------------------------------------------------------------
''' <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 - Função GetIEBrowserEmulationMode e método SetIEBrowserEmulationMode , para obter ou definir o modo de emulação do navegador IE para um aplicativo externo.

''' ----------------------------------------------------------------------------------------------------
''' <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

Exemplo de uso para obter, definir e verificar o modo de emulação do navegador IE para o processo atual:

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/")

Exemplo de uso para obter, definir e verificar o modo de emulação do navegador IE para um processo específico:

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/")

Estou usando o controle WebBrowser no Visual Studio 2010 e tentando exibir a página: http://lk21.org .

Dentro dessa página da web, há muitos scripts carregados, e funcionará bem se eu a abrir através de um navegador da web, como Firefox, Chrome e a versão mais recente do IE.

Minha pergunta é: por que ele exibe "Solicitação incorreta" quando tentei usar o componente WebBrowser para navegar para essa página?

Veja isso:

ATUALIZAR:

A página carrega bem usando a resposta do Visual Vincent.

No entanto, os vídeos em flash no site (ou acho que é algo semelhante ao flash) não podem ser reproduzidos. Veja a comparação nas imagens abaixo.

O estranho é que, se eu abrir o YouTube, o flash funcionará bem. Depois de um pouco de pesquisa, parece ser causado por outra coisa. Alguma pista de como resolvê-lo?

Internet Explorer - funciona bem:

Controle WebBrowser - por algum motivo, o vídeo está travado e não pode ser reproduzido:


Provavelmente, o controle do WebBrowser por padrão usa um modo de emulação de documento do IE 7, o que significa que todas as páginas são tratadas usando o mecanismo do Internet Explorer 7. Como essa versão é bastante antiga, a maioria dos sites hoje não é compatível, o que afeta a funcionalidade quando você visita a página.

Você pode alterar esse comportamento adicionando um valor ao seu aplicativo na chave do Registro Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION na seção HKEY_LOCAL_MACHINE ou no HKEY_CURRENT_USER . Ao fazer isso, você está forçando seu aplicativo a usar uma versão específica do mecanismo do IE.

Eu escrevi uma classe que irá ajudá-lo com isso:

'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

Para usá-lo, coloque uma destas linhas no evento Startup do aplicativo:

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)

( NOTA: O uso da raiz HKEY_LOCAL_MACHINE requer privilégios administrativos)

O método InternetExplorer.SetLatestBrowserEmulation() definirá a emulação do navegador para seu aplicativo, na raiz do registro especificada, para a versão mais recente do Internet Explorer INSTALADA .

No entanto, usando o método InternetExplorer.SetBrowserEmulation() , você pode controlar manualmente qual versão do IE ele deve usar (não recomendado!) .

Consulte Mais informação:

EDITAR

Parece que não consigo entrar nesse site, mas pelo que li, houve problemas com o Flash hospedado no controle WebBrowser .

O que você pode tentar é desativar o recurso de Cache de Objetos ActiveX , o que aparentemente pode causar alguns problemas nos controles do Flash.

Atualizei a classe InternetExplorer acima. Copie e cole e adicione esta linha ao evento de inicialização do seu aplicativo:

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

Se ainda assim não funcionar, temo que você esteja sem sorte. Não consegui encontrar mais nada que seja útil.





webbrowser-control