wpf - WebView2 GarantizaCoreWebView2Async nunca regresa

CorePress2024-01-24  12

En mi aplicación WPF necesito mostrar una cadena html y sé que necesito llamar al método GuaranteeCoreWebView2Async antes de llamar a NavigateToString porque, de lo contrario, CoreWebView será nulo y tendría una excepción. El problema es que la espera de GuaranteeCoreWebView2Async nunca termina.

Creé una pequeña aplicación para reproducir el problema (y excluyendo cuestiones relacionadas con mi gran proyecto) y el problema es el mismo.

Si configuro la propiedad Fuente de WebView2 pasando una URL, ¡entonces funciona! Si llamo a NavigateToString sin llamar a GuaranteeCoreWebView2Async, obtengo una excepción (como se esperaba). Si llamo a GuaranteeCoreWebView2Async antes de llamar a NavigateToString o antes de configurar la propiedad Fuente (no debería ser un problema, porque llamarlo muchas vecess no debería tener ningún efecto según la documentación), luego se cuelga para siempre. La llamada no genera excepciones ni mensajes en la consola. Muy frustrante.

Aquí está el código para la aplicación de muestra (la ventana principal tiene 2 botones, uno que abre la URL y otro que carga la cadena html; el primero funciona):

<Window x:Class="WebViewApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<StackPanel>
    <Button Width="200" Height="40" Click="OpenUrl_Click">Open url</Button>
    <Button Width="200" Height="40" Click="OpenHtml_Click">Open html</Button>
</StackPanel></Window>

Ventana principal detrás del código:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private async void OpenUrl_Click(object sender, RoutedEventArgs e)
    {
        var browserWindow = new WebWindow();
        //await browserWindow.Initialize();  // this also never completes
        browserWindow.OpenUrl("http://www.microsoft.com");
        browserWindow.Show();
    }

    private async void OpenHtml_Click(object sender, RoutedEventArgs e)
    {
        var browserWindow = new WebWindow();
        await browserWindow.Initialize();
        browserWindow.LoadHtml(@"<html><head><title>Test title</title></head><body><p>Test</p></body></html>");
        browserWindow.Show();
    }
}

Aquí está el xaml browserView (agregue el paquete nuget WebView2):

<Window x:Class="WebViewApp.WebWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
    mc:Ignorable="d"
    Title="WebWindow" Height="450" Width="800">
<Grid>
    <wpf:WebView2 Name="WpfBrowser" />
</Grid></Window>

y el código detrás:

public partial class WebWindow : Window
{
    public WebWindow()
    {
        InitializeComponent();
    }

    public async Task Initialize()
    {
        try
        {
            await WpfBrowser.EnsureCoreWebView2Async();  // never completes
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception.Message);
        }
    }

    public void LoadHtml(string html)
    {
        WpfBrowser.NavigateToString(html);
    }

    public void OpenUrl(string url)
    {
        WpfBrowser.Source = new Uri(url);
    }
}

También intenté cambiar la plataforma Target, pero nada cambió.

¿Se bloquea en GuaranteeCoreWebView2Async o genera una excepción? ¿Está utilizando el último control WebView2?

- Poul Bak

27/03/2021 a las 17:01

Sí, se bloquea en GuaranteeCoreWebView2Aync y nunca ingresa la excepción de captura. Estoy usando la última versión preliminar sugerida por nuget (version="1.0.824-prerelease")

-Daniele Armanasco

27/03/2021 a las 18:15



------------------------------------

Debe posponer la inicialización de la vista web hasta que se llame a OnContentRendered. Cambié tu código y funcionó de maravilla. Vea los cambios a continuación.

    public partial class WebWindow : Window
    {
        private string _url;
        private string _html;

        public WebWindow()
        {
            InitializeComponent();
        }

        protected override async void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            try
            {
                var webView2Environment = await CoreWebView2Environment.CreateAsync();
                await WpfBrowser.EnsureCoreWebView2Async(webView2Environment);

                if(!string.IsNullOrEmpty(_url))
                    WpfBrowser.Source = new Uri(_url);
                else if(!string.IsNullOrEmpty(_html))
                    WpfBrowser.NavigateToString(_html);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
            }
        }

        public void ShowFromUrl(string url)
        {
            _url = url;
            Show();
        }

        public void ShowFromHtml(string html)
        {
            _html = html;
            Show();
        }
    }
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void OpenUrl_Click(object sender, RoutedEventArgs e)
        {
            var browserWindow = new WebWindow();
            browserWindow.ShowFromUrl("http://www.microsoft.com");
        }

        private async void OpenHtml_Click(object sender, RoutedEventArgs e)
        {
            var browserWindow = new WebWindow();
            browserWindow.ShowFromHtml(@"<html><head><title>Test title</title></head><body><p>Testsdfsdfsdfsdfdsfdsfklsdkflkdlf<br>dsfdsfdsfdsfsdfdsfds</p></body></html>");
        }
    }

También puedes consultar el código de mi repositorio de git que hace algo similar. Navegador de quiosco (GitHub)

2

2

¡Gracias, también funciona en el "proyecto real"! No se como sabes esto que no encontré por ningún lado, pero estoy muy gmuchacho que lo haces :-)

-Daniele Armanasco

27/03/2021 a las 18:57

2

¿Alguien podría dar más detalles, por favor? Me enfrento a un problema similar que GuaranteeCoreWebView2Async() nunca se completa, pero no estoy usando una aplicación WPF. Entonces, ¿necesitaría entender qué está pasando y por qué no puede inicializarlo solo una vez que se hace clic en el botón?

-NexX

12 de octubre de 2022 a las 10:02



------------------------------------

YoTuve el mismo problema. El uso del controlador de eventos CoreWebView2InitializationCompleted lo resolvió.

Compartir mejorar esta respuesta Seguir Respondido

17 de enero a las 6:36

Presa de Arjan van

Presa de Arjan van

1

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare