Home > Blockchain >  WPF app with embedded WebView2 suddenly shuts down without any visible exception when opening Oookii
WPF app with embedded WebView2 suddenly shuts down without any visible exception when opening Oookii

Time:05-16

I'm trying to use an embedded WebView2 control in my WPF application, and open an Ookii VistaSaveFileDialog in response to communication from the webview.

However, once I've run the dialog's ShowDialog method (which blocks while waiting for a user response) and the dialog is open, the app suddenly shuts down with no exception or warning. This happens intermittently.

It only seems to happen when I've run the code in Debug mode, debugging with VS. Release mode doesn't seem to have this problem.

Deleting the bin and obj folders and rebuilding the solution doesn't help.

How can I go about debugging/resolving this?

Target/version info: TFM: net6.0-windows
WebView2: 1.0.1210.39
Ookii.Dialogs.Wpf: 5.0.1

XAML:

<Window x:Class="_testWebviewDialogs.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wv="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf">
    <wv:WebView2 x:Name="webview" Source="about:blank"/>
</Window>

Code-behind:

using Ookii.Dialogs.Wpf;
using System.IO;
using System.Windows;

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

    private async void initializeAsync() {
        await webview.EnsureCoreWebView2Async();
        var html = await File.ReadAllTextAsync("container.html");
        webview.NavigateToString(html);
        webview.CoreWebView2.WebMessageReceived  = (s, e) => {
            var dlg = new VistaSaveFileDialog();
            dlg.ShowDialog(); // Sometimes the app shuts down while in this (blocking) call
            MessageBox.Show(dlg.FileName);
            webview.CoreWebView2.PostWebMessageAsString(dlg.FileName);
        };
    }
}

container.html, which is copied to the output folder:

<!DOCTYPE html>
<html>
<body>
    <button id="button1">Click me</button>
    <script>
        document.getElementById('button1')
            .addEventListener('click', ev => {
                chrome.webview.postMessage('Hello from webview');
            });
    </script>
</body>
</html>

CodePudding user response:

Per the suggestion I received on the GitHub issue I filed, the following seems to work:

webview.CoreWebView2.WebMessageReceived  = (s, e) => 
    SynchronizationContext.Current!.Post((_) => {
        var dlg = new VistaSaveFileDialog();
        dlg.ShowDialog();
        MessageBox.Show(dlg.FileName);
        webview.CoreWebView2.PostWebMessageAsString(dlg.FileName);
    }, null);

Source: Threading model for WebView2 apps: Reentrancy

  • Related