webview_csharp icon indicating copy to clipboard operation
webview_csharp copied to clipboard

webview.Evaluate doesn't work inside event handlers

Open MitchellMonaghan opened this issue 3 years ago • 1 comments

It seems like webview.Evaluate silently fails when called inside a event handler. Here is a basic example reproducing the issue. Not sure if this is a C# binding issue or the core webview project.

using System;
using System.Timers;
using SharpWebview;
using SharpWebview.Content;

namespace Minimal
{
    class Program
    {
        // Set the application to Single Threaded Apartment
        // Otherwise the webview won't work on windows at least
        [STAThread]
        static void Main(string[] args)
        {
            // Wrap the usage of the webview into a using block
            // Otherwise the native window will not get disposed correctly
            using(var webview = new Webview(true))
            {
                // Create a timer with a two second interval.
                Timer aTimer = new Timer(2000);
                // Hook up the Elapsed event for the timer. 
                aTimer.Elapsed += (Object source, ElapsedEventArgs e) => {
                    try
                    {
                        Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
                                          e.SignalTime);

                        webview.Evaluate("console.log('test')");
                    }
                    catch (Exception error) {
                        Console.WriteLine(error.Message);
                    }
                };
                aTimer.AutoReset = true;
                aTimer.Start();

                webview
                    // Set the title of the application window
                    .SetTitle("The Hitchhicker")
                    // Set the start size of the window                
                    .SetSize(1024, 768, WebviewHint.None)
                    // Set the minimum size of the window
                    .SetSize(800, 600, WebviewHint.Min)
                    // This script gets executed after navigating to the url
                    .InitScript("window.x = 42;")
                    // Bind a c# function to the webview - Accessible with the name "evalTest"
                    .Bind("evalTest", (id, req) =>
                    {
                        // Executes the javascript on the webview
                        webview.Evaluate("console.log('The anwser is ' + window.x);");
                        // And returns a successful promise result to the javascript function, which executed the 'evalTest'
                        webview.Return(id, RPCResult.Success, "{ result: 'We always knew it!' }");
                    })
                    // Navigate to this url on start
                    .Navigate(new UrlContent("https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy_(novel)"))
                    // Run the webview loop
                    .Run();
            }
        }
    }
}

MitchellMonaghan avatar Nov 12 '20 06:11 MitchellMonaghan

This doesn't seem to be SharpWebview specific, and seems to be a thread affinity issue, and seems to be a limitation of the underlying webview control.

I managed to make it work by using .Dispatch

webview.Dispatch(() =>
{
    webview.Evaluate("console.log('test')");
});

milleniumbug avatar Jan 08 '22 09:01 milleniumbug