C# Webview2 WebMessageReceived event not firing anymore after update of MS Edge browser and Webview2 runtime

126 Views Asked by At

I am developing a WinForms project using VS2022 IDE. as per our requirement I am using Webview2 to embed the browser in our WinForms. web site load properly. my requirement was if user select any data from Webview2 at runtime then I need to capture the html of that selected text. this way i did it and it was working fine.

please see me code which was working for last 30 days.

public partial class Form1 : Form
{
        Microsoft.Web.WebView2.WinForms.WebView2 webViewControl = null;
        string selectedHtml = "";
        public Form1()
        {
            InitializeComponent();
            InitBrowserControl();
        }

        private async void InitBrowserControl()
        {
            webViewControl = new Microsoft.Web.WebView2.WinForms.WebView2();
            webViewControl.Dock = System.Windows.Forms.DockStyle.Fill;

            // Handle the WebView2's CoreWebView2InitializationCompleted event
            webViewControl.CoreWebView2InitializationCompleted += async (s, evt) =>
            {
                // Inject JavaScript to retrieve selected text's HTML by javascript
                string script = @"
                    console.log('Script is running in the browser context!');
                    document.onmouseup = function() {
                        var selection = window.getSelection();
                        var range = selection.getRangeAt(0);
                        var clonedRange = range.cloneRange();
                        var div = document.createElement('div');
                        div.appendChild(clonedRange.cloneContents());
                        var selectedHtml = div.innerHTML;
                        console.log(div.innerHTML);
                        window.chrome.webview.postMessage(selectedHtml);
                    };
                ";

                await webViewControl.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);
                await Task.Delay(0); // Yield to event loop
            };

            // Handle the WebView2's WebMessageReceived event
            webViewControl.WebMessageReceived += (s, evt) =>
            {
                selectedHtml = evt.WebMessageAsJson;
            };

            await webViewControl.EnsureCoreWebView2Async(null);

            // Attach the event handler
            webViewControl.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
            webViewControl.CoreWebView2.HistoryChanged += CoreWebView2_HistoryChanged;
            webViewControl.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
            webViewControl.CoreWebView2.NavigationStarting += CoreWebView2_NavigationStarting;
            panel1.Controls.Add(webViewControl);
        }
}       

if anyone see my code then they can understand i inject a JavaScript into Webview2 browser which will fire onmouseup and store html into a js variable and later push that data to client side by window.chrome.webview.postMessage(selectedHtml)

i was getting html data from WebMessageReceived event.

everything was working as expected but just 2 days back my MS Edge Browser and Webview2 runtime was updated automatically which causes the problem. after update of MS Edge Browser and Webview2 runtime my WebMessageReceived event not firing anymore. last 2 days i searched google lot but still no luck.

Please guys help me to figure out the problem and how to fix this issue as a result WebMessageReceived event should fire like before.

my MS Edge Browser current version is 122.0.2365.92 (Official build) (64-bit) my Webview2 runtime version is also 122.0.2365.92

Please tell me if i made any mistake in code. Please help me how to figure out and fix this issue.

Thanks

1

There are 1 best solutions below

3
user246821 On

The code below has been refactored and shows how/when to use async Task and where to use async void so that WebView2 works correctly.

Pre-requisites:

Note: See Release Notes for the WebView2 SDK for more information.

Create a new Windows Forms App - I used .NET 8 for testing.

using System.Diagnostics;

namespace Webview2DetectSelectedHTML
{
    public partial class Form1 : Form
    {
        Microsoft.Web.WebView2.WinForms.WebView2 webViewControl = null;
        string selectedHtml = "";

        public Form1()
        {
            InitializeComponent();
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            await InitBrowserControl();

            //navigate
            LogMsg("Form1_Load - Setting WebView2.Source");
            webViewControl.Source = new Uri("https://www.google.com/search?q=webview2");
        }

        private async Task InitBrowserControl()
        {
            //create new instance
            webViewControl = new Microsoft.Web.WebView2.WinForms.WebView2();
            webViewControl.Dock = System.Windows.Forms.DockStyle.Fill;

            // subscribe to events
            webViewControl.CoreWebView2InitializationCompleted += WebViewControl_CoreWebView2InitializationCompleted;
            webViewControl.WebMessageReceived += WebViewControl_WebMessageReceived;

            //initialize CoreWebView2
            await webViewControl.EnsureCoreWebView2Async(null);

            // Inject JavaScript to retrieve selected text's HTML by javascript
            string script = @"
                    console.log('Script is running in the browser context!');
                    document.onmouseup = function() {
                        var selection = window.getSelection();
                        var range = selection.getRangeAt(0);
                        var clonedRange = range.cloneRange();
                        var div = document.createElement('div');
                        div.appendChild(clonedRange.cloneContents());
                        var selectedHtml = div.innerHTML;
                        console.log(div.innerHTML);
                        window.chrome.webview.postMessage(selectedHtml);
                    };
                ";

            //add script
            await webViewControl.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);

            // subscribe to CoreWebView2 events
            webViewControl.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
            webViewControl.CoreWebView2.HistoryChanged += CoreWebView2_HistoryChanged;
            webViewControl.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
            webViewControl.CoreWebView2.NavigationStarting += CoreWebView2_NavigationStarting;

            //add
            panel1.Controls.Add(webViewControl);
        }

        private void WebViewControl_WebMessageReceived(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs e)
        {
            //set value
            selectedHtml = e.WebMessageAsJson;

            LogMsg(selectedHtml);
        }

        private void WebViewControl_CoreWebView2InitializationCompleted(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            LogMsg("WebViewControl_CoreWebView2InitializationCompleted");
        }

        private void LogMsg (string msg, bool includeDateTime = true)
        {
            if (includeDateTime)
                msg = $"{DateTime.Now.ToString("HH:mm:ss.fff")} - {msg}";

            Debug.WriteLine (msg);
        }


        private void CoreWebView2_NavigationStarting(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e)
        {
            LogMsg("CoreWebView2_NavigationStarting");
        }

        private void CoreWebView2_NewWindowRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
        {
            LogMsg("CoreWebView2_NewWindowRequested");
        }

        private void CoreWebView2_HistoryChanged(object? sender, object e)
        {
            LogMsg("CoreWebView2_HistoryChanged");
        }

        private void CoreWebView2_NavigationCompleted(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
        {
            LogMsg("CoreWebView2_NavigationCompleted");
        }
    }
}


Update:

If you're using .NET Framework v.4.8, in the code above, change all occurrences of object? to object.


Here's a demonstration:

enter image description here