Navegador

Este guia descreve como criar, utilizar e fechar o Navegador.

Consulte o guia Arquitetura para obter mais informações sobre a arquitetura do DotNetBrowser, seus principais componentes e sua interação.

Criando um navegador

Para criar uma nova instância do IBrowser , utilize o método IProfile.CreateBrowser() . Por exemplo:

IBrowser browser = engine.Profiles.Default.CreateBrowser();
Dim browser As IBrowser = engine.Profiles.Default.CreateBrowser()

Se utilizar o método IEngine.CreateBrowser(), o navegador é criado com o perfil predefinido. No entanto, esta abordagem é obsoleta e recomenda-se a utilização da instância de perfil correspondente.

Este método executa as seguintes ações:

  1. Cria uma nova instância do IBrowser .
  2. Carrega a página web about:blank e aguarda até que a página web esteja completamente carregada.

Eliminando um navegador

A instância IBrowser é executada no processo Chromium Main e atribui memória e recursos do sistema a serem libertados. Quando uma instância do IBrowser já não for necessária, elimine-a utilizando o método IBrowser.Dispose() . Como resultado, toda a memória alocada e os recursos do sistema são libertados. Veja o exemplo de código abaixo:

IBrowser browser = engine.Profiles.Default.CreateBrowser();
// ...
browser.Dispose();
Dim browser As IBrowser = engine.Profiles.Default.CreateBrowser()
' ...
browser.Dispose()

Uma tentativa de utilizar uma instância do IBrowser já descartada leva à ObjectDisposedException.

A instância IBrowser é eliminada automaticamente nos seguintes casos:

  1. Quando a sua instância principal IEngine é eliminada ou sofre um acidente inesperado.
  2. Quando esta instância do IBrowser é um pop-up que é fechado a partir do JavaScript utilizando window.close().

Utilize o evento Disposed para ser notificado quando a instância do IBrowser for eliminada. Veja o exemplo de código abaixo:

browser.Disposed += (sender, event => {});
AddHandler browser.Disposed, Sub(s,e)
End Sub

Utilize a propriedade IsDisposed para verificar se o IBrowser já foi eliminado:

bool disposed = browser.IsDisposed;
Dim disposed As Boolean = browser.IsDisposed

Tamanho do navegador

Por padrão, o tamanho do IBrowser está vazio. Se pretender trabalhar com DOM ou Localizar texto numa página Web, defina primeiro o tamanho do navegador.

Para atualizar o tamanho do IBrowser, utilize a sua propriedade Size . Veja o exemplo de código abaixo:

browser.Size = new Size(800, 600);
browser.Size = New Size(800, 600)

Este método notifica o Chromium que o tamanho da instância do IBrowser foi alterado. O Chromium actualizará a disposição DOM da página Web carregada e repintará o seu conteúdo de forma assíncrona. Poderá demorar algum tempo até que a página Web seja repintada após a definição da propriedade.

Definições do navegador

É possível personalizar as definições do navegador através da propriedade IBrowser.Settings. As definições do navegador podem ser utilizadas para desativar imagens, plugins ou JavaScript no navegador, ocultar barras de deslocamento, desativar o cache da aplicação. Veja o exemplo de código abaixo:

// Desabilita todos os scripts.
browser.Settings.JavaScriptEnabled = false;
' Desativar todos os scripts.
browser.Settings.JavaScriptEnabled = False

Especificando a Política de Tratamento de IP WebRTC

O DotNetBrowser permite personalizar a política de tratamento do IP WebRTC. Estas são as políticas WebRTC disponíveis no DotNetBrowser:

  • Default - comportamento padrão do Chromium. Quando esta política é definida, o WebRTC pode enumerar todas as interfaces e ligá-las para descobrir interfaces públicas.

  • DefaultPublicInterfacesOnly - diz ao navegador para enviar tráfego WebRTC utilizando o adaptador de rede pública predefinido. Este será o adaptador VPN para os utilizadores do sistema-VPN. O WebRTC deve utilizar apenas a rota predefinida utilizada pelo http.

  • DefaultPublicAndPrivateInterfaces - igual a DefaultPublicInterfacesOnly exceto que permite o tráfego WebRTC através da interface privada predefinida para a sua rede local também.

  • DisableNonProxiedUdp - desativa o UDP sem proxy e força o proxy. Esta política força a utilização de um proxy e apenas permite o tráfego WebRTC através de proxies UDP. Ela desativa efetivamente a comunicação WebRTC para a maioria dos usuários, dependendo da utilização do proxy UDP.

O código de exemplo a seguir demonstra como configurar a política de tratamento de IP WebRTC para uma instância do Navegador:

browser.Settings.WebRtcIpHandlingPolicy = 
    WebRtcIpHandlingPolicy.DisableNonProxiedUdp;
browser.Settings.WebRtcIpHandlingPolicy = 
    WebRtcIpHandlingPolicy.DisableNonProxiedUdp

Modo escuro

Você pode forçar o esquema de cores preferido na página Web da seguinte forma:

// Força o modo escuro.
browser.Settings.PreferredColorScheme = PreferredColorScheme.Dark;
// Força o modo claro.
browser.Settings.PreferredColorScheme = PreferredColorScheme.Light;
' Força o modo escuro.
browser.Settings.PreferredColorScheme = PreferredColorScheme.Dark 
' Força o modo claro.
browser.Settings.PreferredColorScheme = PreferredColorScheme.Light 

As configurações acima só serão aplicadas nos sites que respeitam a consulta de mídia prefers-color-scheme.

Agente do Usuário

É possível substituir a cadeia de caracteres predefinida do Agente do Usuário e configurar o IBrowser para utilizar uma cadeia de caracteres personalizada. Veja o exemplo de código abaixo:

browser.UserAgent = "<user-agent>";
browser.UserAgent = "<user-agent>"

A mesma propriedade pode ser utilizada para obter a cadeia de caracteres do agente do usuário atual:

string userAgent = browser.UserAgent;
Dim userAgent As String = browser.UserAgent

URL de depuração remota

Para obter o URL de depuração remota de uma página da Web carregada em uma instância específica do IBrowser , use a seguinte abordagem:

string url = browser.DevTools.RemoteDebuggingUrl;
Dim url As String = browser.DevTools.RemoteDebuggingUrl

Esta abordagem retorna uma URL válida somente se o IEngine estiver configurado com a Porta de Depuração Remota. Caso contrário, o valor da propriedade é nulo.

DevTools

Para mostrar a janela DevTools programaticamente sem configurar a porta de depuração remota, use o seguinte código:

browser.DevTools.Show();
browser.DevTools.Show()

DevTools

Ver fonte da página

Pode ver a fonte da página Web ou do frame carregado utilizando o seguinte método:

browser.MainFrame?.ViewSource();
browser.MainFrame?.ViewSource()

O código acima diz ao Chromium para criar e abrir uma janela pop-up com a fonte HTML do frame principal.

Fonte da página

Eventos do mouse e do teclado

O DotNetBrowser permite intercetar os eventos do mouse e do teclado antes de serem enviados para a página web utilizando os seguintes manipuladores:

  • IBrowser.Mouse.Entered.Handler
  • IBrowser.Mouse.Exited.Handler
  • IBrowser.Mouse.Pressed.Handler
  • IBrowser.Mouse.Released.Handler
  • IBrowser.Mouse.Moved.Handler
  • IBrowser.Mouse.WheelMoved.Handler
  • IBrowser.Keyboard.KeyPressed.Handler
  • IBrowser.Keyboard.KeyTyped.Handler
  • IBrowser.Keyboard.KeyReleased.Handler

A seguinte amostra de código demonstra como suprimir os eventos de roda do mouse:

browser.Mouse.WheelMoved.Handler = 
    new Handler<IMouseWheelMovedEventArgs, InputEventResponse>(e =>
    {
        return InputEventResponse.Suppress;
    });
browser.Mouse.WheelMoved.Handler = 
    New Handler(Of IMouseWheelMovedEventArgs, InputEventResponse)(Function(e)
        Return InputEventResponse.Suppress
    End Function)

Você ode utilizar estes manipuladores para obter as notificações sobre os eventos do mouse e do teclado para implementar teclas de atalho na sua aplicação. Você também pode suprimir os atalhos predefinidos, tais como Ctrl+C. Veja o exemplo de código abaixo:

browser.Keyboard.KeyPressed.Handler = 
    new Handler<IKeyPressedEventArgs, InputEventResponse>(e =>
    {
        bool keyCodeC = e.VirtualKey == KeyCode.VkC;
        bool controlDown = e.Modifiers.ControlDown;
        if (controlDown && keyCodeC) 
        {
            return InputEventResponse.Suppress;
        }
        return InputEventResponse.Proceed;
    });
browser.Keyboard.KeyPressed.Handler = 
    New Handler(Of IKeyPressedEventArgs, InputEventResponse)(Function(e)
        Dim keyCodeC As Boolean = e.VirtualKey = KeyCode.VkC
        Dim controlDown As Boolean = e.Modifiers.ControlDown
        If controlDown AndAlso keyCodeC Then
            Return InputEventResponse.Suppress
        End If
        Return InputEventResponse.Proceed
    End Function)

Simular a entrada de dados do usuário

O DotNetBrowser permite simular eventos do mouse e do teclado. A simulação está disponível nos modos de renderização fora da tela e acelerada por hardware para WPF e Windows Forms.

É possível simular a entrada de dados através da criação de eventos do mouse e teclado. Por exemplo, eis como simular a digitação:

private static void SimulateKey(IKeyboard keyboard, KeyCode key, string keyChar,
                                KeyModifiers modifiers = null)
{
    modifiers = modifiers ?? new KeyModifiers();
    KeyPressedEventArgs keyDownEventArgs = new KeyPressedEventArgs
    {
        KeyChar = keyChar,
        VirtualKey = key,
        Modifiers = modifiers
    };

    KeyTypedEventArgs keyPressEventArgs = new KeyTypedEventArgs
    {
        KeyChar = keyChar,
        VirtualKey = key,
        Modifiers = modifiers
    };
    KeyReleasedEventArgs keyUpEventArgs = new KeyReleasedEventArgs
    {
        VirtualKey = key,
        Modifiers = modifiers
    };

    keyboard.KeyPressed.Raise(keyDownEventArgs);
    keyboard.KeyTyped.Raise(keyPressEventArgs);
    keyboard.KeyReleased.Raise(keyUpEventArgs);
}
Private Shared Sub SimulateKey(keyboard As IKeyboard, key As KeyCode, keyChar As String,
                               Optional modifiers As KeyModifiers = Nothing)
    modifiers = If(modifiers, New KeyModifiers())
    Dim keyPressedEventArgs = New KeyPressedEventArgs With {
        .KeyChar = keyChar,
        .VirtualKey = key,
        .Modifiers = modifiers
    }

    Dim keyTypedEventArgs = New KeyTypedEventArgs With {
        .KeyChar = keyChar,
        .VirtualKey = key,
        .Modifiers = modifiers
    }
        
    Dim keyReleasedEventArgs = New KeyReleasedEventArgs With {
        .VirtualKey = key,
        .Modifiers = modifiers
    }

    keyboard.KeyPressed.Raise(keyPressedEventArgs)
    keyboard.KeyTyped.Raise(keyTypedEventArgs)
    keyboard.KeyReleased.Raise(keyReleasedEventArgs)
End Sub
IKeyboard keyboard = browser.Keyboard;
SimulateKey(keyboard, KeyCode.VkH, "H");
SimulateKey(keyboard, KeyCode.VkE, "e");
SimulateKey(keyboard, KeyCode.VkL, "l");
SimulateKey(keyboard, KeyCode.VkL, "l");
SimulateKey(keyboard, KeyCode.VkO, "o");
SimulateKey(keyboard, KeyCode.Space, " ");
// Simular a introdução de alguns caracteres não alfabéticos.
SimulateKey(keyboard, KeyCode.Vk5, "%", new KeyModifiers {ShiftDown = true});
SimulateKey(keyboard, KeyCode.Vk2, "@", new KeyModifiers {ShiftDown = true});
Dim keyboard As IKeyboard = browser.Keyboard
SimulateKey(keyboard, KeyCode.VkH, "H")
SimulateKey(keyboard, KeyCode.VkE, "e")
SimulateKey(keyboard, KeyCode.VkL, "l")
SimulateKey(keyboard, KeyCode.VkL, "l")
SimulateKey(keyboard, KeyCode.VkO, "o")
SimulateKey(keyboard, KeyCode.Space, " ")
' Simular a introdução de alguns caracteres não alfabéticos.
SimulateKey(keyboard, KeyCode.Vk5, "%",
            New KeyModifiers() With {.ShiftDown = True})
SimulateKey(keyboard, KeyCode.Vk2, "@",
            New KeyModifiers() With {.ShiftDown = True})

Os exemplos completos estão disponíveis no nosso repositório:

WinForms (C#, VB.NET)
WPF (C#, VB.NET)

Pode simular o clique do mouse aumentando os eventos IMouse.Moved, IMouse.Pressede IMouse.Released numa sequência. Por exemplo, eis como simular um único clique:

IMouse mouse = browser.Mouse;
MouseButton mouseButton = MouseButton.Left;
Point location = new Point(10, 10);

MouseMovedEventArgs moveEvent = new MouseMovedEventArgs
{
    Location = location
};

MousePressedEventArgs pressEvent = new MousePressedEventArgs
{
    Location = location,
    Button = mouseButton,
    ClickCount = 1
};

MouseReleasedEventArgs releaseEvent = new MouseReleasedEventArgs
{
    Button = mouseButton,
    ClickCount = 1,
    Location = location
};

mouse.Moved.Raise(moveEvent);
Thread.Sleep(200);
mouse.Pressed.Raise(pressEvent);
Thread.Sleep(200);
mouse.Released.Raise(releaseEvent);
Dim mouse As IMouse = browser.Mouse
Dim mouseButton As MouseButton = MouseButton.Left
Dim location As New Point(10, 10)

Dim moveEvent As New MouseMovedEventArgs With {.Location = location}

Dim pressEvent As New MousePressedEventArgs With {
    .Location = location,
    .Button = mouseButton,
    .ClickCount = 1
}

Dim releaseEvent As New MouseReleasedEventArgs With {
    .Button = mouseButton,
    .ClickCount = 1,
    .Location = location
}

mouse.Moved.Raise(moveEvent)
Thread.Sleep(200)
mouse.Pressed.Raise(pressEvent)
Thread.Sleep(200)
mouse.Released.Raise(releaseEvent)

Compartilhamento de tela WebRTC

O Chromium fornece uma funcionalidade integrada que permite compartilhar toda a tela, uma janela de aplicação ou uma página Web. Por padrão, o DotNetBrowser apresenta uma caixa de diálogo padrão onde o usuário pode selecionar a fonte de captura:

WebRTC

Se você não pretende apresentar esta caixa de diálogo, é possível tratar os pedidos e selecionar a origem da captura de forma programática. Por exemplo:

browser.Capture.StartSessionHandler = 
    new Handler<StartSessionParameters, StartSessionResponse>(p =>
{
    // Diz à instância do navegador para iniciar uma nova sessão de captura e especificar a
    // fonte de captura.
    return StartSessionResponse.SelectSource(p.Sources.Screens.FirstOrDefault(),
                                             AudioMode.Ignore);
});
browser.Capture.StartSessionHandler = 
    New Handler(Of StartSessionParameters, StartSessionResponse)(Function(p)
        ' Diz à instância do navegador para iniciar uma nova sessão de captura e especificar a
        ' fonte de captura.
    Return StartSessionResponse.SelectSource(p.Sources.Screens.FirstOrDefault(),
                                            AudioMode.Ignore)
End Function)

Para interromper a sessão de forma programática, utilize a seguinte abordagem:

// Obtém todas as sessões de captura do navegador atual.
IReadOnlyList<ISession> sessions = browser.Capture.Sessions;
foreach (ISession session in sessions)
{
    string sourceName = session.Source.Name;
    bool isActive = session.IsActive;

    // Pára a sessão.
    session.Stop();
}
' Obter todas as sessões de captura do navegador atual.
Dim sessions As IReadOnlyList(Of ISession) = browser.Capture.Sessions
For Each session As ISession In sessions
    Dim sourceName As String = session.Source.Name
    Dim isActive As Boolean = session.IsActive

    ' Parar a sessão.
    session.Stop()
Next 

Você também pode suprimir os pedidos de compartilhamento de tela e a caixa de diálogo padrão. Eis o exemplo:

browser.Capture.StartSessionHandler =
    new Handler<StartSessionParameters, StartSessionResponse>(p =>
{
    // Cancelar a ação de compartilhamento.
    return StartSessionResponse.Cancel();
});
browser.Capture.StartSessionHandler = 
    New Handler(Of StartSessionParameters, StartSessionResponse)(Function(p)
        ' Cancelar a ação de compartilhamento.
    Return StartSessionResponse.Cancel()
End Function)

Arrastar e Soltar

Desde o DotNetBrowser 2.3, é possível intercetar os eventos de arrastar e soltar na página da Web no modo de renderização acelerada por hardware. Para este efeito, é necessário utilizar o EnterDragHandler e o DropHandler. Por exemplo:

browser.DragAndDrop.EnterDragHandler =
    new Handler<EnterDragParameters>(OnDragEnter);
browser.DragAndDrop.DropHandler = new Handler<DropParameters>(OnDrop);
browser.DragAndDrop.EnterDragHandler =
    New Handler(Of EnterDragParameters)(AddressOf OnDragEnter)
browser.DragAndDrop.DropHandler = New Handler(Of DropParameters)(AddressOf OnDrop)
private void OnDragEnter(EnterDragParameters arg)
{
    if (arg.Event.DropData != null)
    {
        //Escreve os nomes dos arquivos para depurar a saída.
        foreach (IFileValue file in arg.Event.DropData.Files)
        {
            Debug.WriteLine($"OnDragEnter: File = {file?.FileName}");
        }
    }
}

private void OnDrop(DropParameters arg)
{
    if (arg.Event.DropData != null)
    {
        //Escreve os nomes dos arquivos na saída de depuração.
        foreach (IFileValue file in arg.Event.DropData.Files)
        {
            Debug.WriteLine($"OnDrop: File = {file?.FileName}");
        }
    }
}
Private Sub OnDragEnter(arg As EnterDragParameters)
    If arg.Event.DropData IsNot Nothing Then
        ' Escreve os nomes dos arquivos na saída de depuração.
        For Each file As IFileValue In arg.Event.DropData.Files
            Debug.WriteLine($"OnDragEnter: File = {file?.FileName}")
        Next file
    End If
End Sub

Private Sub OnDrop(arg As DropParameters)
    If arg.Event.DropData IsNot Nothing Then
        ' Escreve os nomes dos arquivos na saída de depuração.
        For Each file As IFileValue In arg.Event.DropData.Files
            Debug.WriteLine($"OnDrop: File = {file?.FileName}")
        Next file
    End If
End Sub

No .NET Framework, também é possível trabalhar com a instância IDataObject no âmbito destes manipuladores para receber e processar a representação específica do Windows dos dados arrastados e largados. Esta funcionalidade fica disponível quando a opção --enable-com-in-drag-drop Chromium switch é especificada. Por exemplo:

private void OnDragEnter(EnterDragParameters arg)
{
    LogData(arg.Event.DropData, nameof(OnDragEnter));
    Debug.WriteLine($"Data is null? {(arg.Event.DataObject == null)}");

    System.Runtime.InteropServices.ComTypes.IDataObject dataObject =
        arg.Event.DataObject;
    if (dataObject != null)
    {
        // Processar dados em IDataObject
        ExtractData(nameof(OnDragEnter), new DataObject(dataObject));
    }
}

private void OnDrop(DropParameters arg)
{
    LogData(arg.Event.DropData, nameof(OnDrop));
    Debug.WriteLine($"Data is null? {(arg.Event.DataObject == null)}");

    System.Runtime.InteropServices.ComTypes.IDataObject dataObject =
        arg.Event.DataObject;
    if (dataObject != null)
    {
        // Processar dados em IDataObject
        ExtractData(nameof(OnDrop), new DataObject(dataObject));
    }
}
Private Sub OnDragEnter(arg As EnterDragParameters)
    LogData(arg.Event.DropData, NameOf(OnDragEnter))
    Debug.WriteLine($"Os dados são nulos? {(arg.Event.DataObject Is Nothing)}")
    Dim dataObject As IDataObject = arg.Event.DataObject

    If dataObject IsNot Nothing Then
        ' Processar dados em IDataObject.
        ExtractData(NameOf(OnDragEnter), New DataObject(dataObject))
    End If
End Sub

Private Sub OnDrop(arg As DropParameters)
    LogData(arg.Event.DropData, NameOf(OnDrop))
    Debug.WriteLine($"Os dados são nulos? {(arg.Event.DataObject Is Nothing)}")
    Dim dataObject As IDataObject = arg.Event.DataObject

    If dataObject IsNot Nothing Then
        ' Processar dados em IDataObject.
        ExtractData(NameOf(OnDrop), New DataObject(dataObject))
    End If
End Sub

Para um exemplo completo, navegue até ao nosso repositório: C#, VB.NET.

No modo de renderização fora da tela, a função arrastar e soltar não é suportada e está completamente desativada.

Eventos de título

O evento TitleChanged indica que o título de um documento no frame principal foi alterado.

Para receber notificações quando o título de um documento é alterado, utilize o listener TitleChanged, conforme mostrado no exemplo de código abaixo:

browser.TitleChanged += delegate (object sender, TitleChangedEventArgs e)
{
    string mainDocumentTitle = e.Title;
};
AddHandler browser.TitleChanged, Sub(sender As Object, e As TitleChangedEventArgs)
    Dim mainDocumentTitle As String = e.Title
End Sub

Eventos de estado

Quando o usuário move o cursor sobre um link, o engine Chromium apresenta o seu URL na barra de estado. O código JavaScript pode alterar o texto na barra de estado programaticamente usando o window.statusproperty também. A API DotNetBrowser fornece funcionalidade para obter notificações sobre alterações no texto da barra de estado.

StatusChanged indica que o texto da barra de estado foi alterado.

O exemplo de código abaixo demonstra como utilizar esta funcionalidade:

browser.StatusChanged += delegate(object sender, StatusChangedEventArgs e)
{
    string statusText = e.Text;
};
AddHandler browser.StatusChanged, Sub(sender As Object, e As StatusChangedEventArgs)
    Dim statusText As String = e.Text
End Sub

Evento de encerramento do processo de renderização

Cada instância do IBrowser está ligada a um processo nativo separado onde a página Web é processada. Por padrão, o Chromium cria um processo de processamento para cada instância de um sítio Web que o usuário visita. Isto garante que as páginas de diferentes sites Web são processadas de forma independente e que as visitas separadas ao mesmo site Web também são isoladas umas das outras. Assim, as falhas (por exemplo, falhas do renderizador) ou a utilização intensiva de recursos numa instância de um site não afetam o resto do navegador.

Por vezes, este processo pode terminar de forma inesperada. Para receber notificações sobre o fim do processo de processamento, você pode se inscrever no evento IBrowser.RenderProcessTerminated. O valor RenderProcessTerminatedEventArgs.ExitCode pode ser utilizado para determinar se se trata de um fim de processo esperado ou de uma falha.

Quando você recebe uma notificação sobre o fim inesperado do processo de renderização, você pode apresentar um ícone “triste” como o Google Chrome faz, por exemplo, para informar o usuário sobre esta falha específica da instância.

Se atualizar ou carregar o mesmo ou outro URL após o acidente, o processo de renderização e a instância IBrowser são restaurados:

browser.RenderProcessTerminated += (sender, e) =>
{
    int exitCode = e.ExitCode;
    if (exitCode != 0)
    {
        // O processo de renderização terminou inesperadamente.
    }
};
AddHandler browser.RenderProcessTerminated, Sub(sender, e)
    Dim exitCode As Integer = e.ExitCode
    If exitCode <> 0 Then
        ' O processo de renderização terminou inesperadamente.
    End If
End Sub
Go Top