11
string text = "return 'test';";
var webView = new Microsoft.Web.WebView2.WinForms.WebView2();
webView.EnsureCoreWebView2Async(null).RunSynchronously();
var srun = webView.CoreWebView2.ExecuteScriptAsync(text);

When I run the above code EnsureCoreWebView2Async is getting this exception

"Cannot change thread mode after it is set. (Exception from HRESULT: 0x80010106 (RPC_E_CHANGED_MODE))"

What do I need to do to run this with out a winform dlg in a console or windows service?

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
Aaron Fischer
  • 20,853
  • 18
  • 75
  • 116
  • 2
    It probably needs a SynchronizationContext, so it can capture an execution Context (its Scheduler) it can resume to. `RunSynchronously()` cannot be used here. – Jimi Mar 19 '21 at 12:38
  • Just as a reference, it seems that using `HWND_MESSAGE` as described in [#202](https://github.com/MicrosoftEdge/WebView2Feedback/issues/202) allows to use WebView2 headless e.g. in a .NET Console application. – Uwe Keim May 03 '23 at 18:11

1 Answers1

12

It turns out the key thing is to add [STAThread] to the Main function.

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Microsoft.Web.WebView2.WinForms.WebView2 webView21 = new Microsoft.Web.WebView2.WinForms.WebView2();

        var ecwTask = webView21.EnsureCoreWebView2Async(null);
        while (ecwTask.IsCompleted == false)
        {
            Application.DoEvents();
        };

        var scriptText = @"var test = function(){ return 'apple';}; test();";
        var srunTask = webView21.ExecuteScriptAsync(scriptText);
        while (srunTask.IsCompleted == false)
        {
            Application.DoEvents();
        };

        Console.WriteLine(srunTask.Result);
    }
}

Other items that maybe note worthy,

  • Sometimes you need to set the bitness of the application because use of AnyCPU will cause an infinite wait when creating the WebView2 COM object.
  • You may need to set the webview2 source property to foce the instance into existance.
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Aaron Fischer
  • 20,853
  • 18
  • 75
  • 116
  • 5
    I just learned, **DON'T** use `async Task Main()`, because [it doesn't work with `STAThread`](https://github.com/dotnet/roslyn/issues/22112). _(Took me 1 hour to find this bug.)_ – JHBonarius Jul 19 '22 at 10:14