As per Microsoft's Getting Started with webView2 in Windows Forms (as of 2021 March 9), I've got the following code (with webView2.source not set; edited out of Form.Designer.cs):
public Form1() {
InitializeComponent();
InitializeAsync();
}
async void InitializeAsync() {
Console.WriteLine("InitializeAsync starting");
await webView2.EnsureCoreWebView2Async(null);
Console.WriteLine("InitializeAsync done");
}
private void Form1_Load(object sender, EventArgs e) {
Console.WriteLine("Load event");
}
private void webView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) {
Console.WriteLine("CoreWebView2InitializationCompleted event");
if ((webView2 == null) || (webView2.CoreWebView2 == null))
Console.WriteLine("not ready");
webView2.NavigateToString(File.ReadAllText("index.html"));
}
I'm surprised to get an exception at the NavigateToString():
System.InvalidOperationException
HResult=0x80131509
Message=The instance of CoreWebView2 is uninitialized and unable to complete this operation. See InitializeAsync.
Source=Microsoft.Web.WebView2.WinForms
StackTrace:
at Microsoft.Web.WebView2.WinForms.WebView2.VerifyInitializedGuard()
at Microsoft.Web.WebView2.WinForms.WebView2.NavigateToString(String htmlContent)
at webview2_base.Form1.webView2_CoreWebView2InitializationCompleted(Object sender, CoreWebView2InitializationCompletedEventArgs e) in E:\Visual Studio 2019\source\repos\explore\webview2_base\Form1.cs:line 37
at Microsoft.Web.WebView2.WinForms.WebView2.<InitCoreWebView2Async>d__13.MoveNext()
The console output is:
InitializeAsync starting
Load event
CoreWebView2InitializationCompleted event
Exception thrown: 'System.InvalidOperationException' in Microsoft.Web.WebView2.WinForms.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.Web.WebView2.WinForms.dll but was not handled in user code
The instance of CoreWebView2 is uninitialized and unable to complete this operation. See InitializeAsync.
What's up with that? I would have thought CoreWebView2 would have completed its initialization, given the label of the event.
The code works if the Navigate is moved to after the 'await' in InitializeAsync. I probably don't understand 'await', I thought it would delay the completion of the Form constructor, and the Load event, until after CoreWebView2 completed.
I'd like to put the Navigate in the Form Load event handler (but it fires before CoreWebView2 is ready).
Am I not understanding something, or is there a bug here relating to CoreWebView2 not being initialized even after it's 'initializeComplete' event has fired?
VS2019 16.9, Net 4.7.2, webview2 version 91.0.823.0 canary
Update (2021-03-19): It works if 'webView2.NavigateToString()' is replaced with 'webView2.CoreWebView2.NavigateToString()'. But given the event name, it seems either should work at that point.
You need to use await InitializeAsync();
which means async void InitializeAsync
should be async Task InitializeAsync
. Since async
can't be used with a constructor, you'll have to call InitializeAsync from Form1_Load
.
Try the following:
using System.Diagnostics;
Option 1:
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
webView2.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
Debug.WriteLine("before InitializeAsync");
await InitializeAsync();
Debug.WriteLine("after InitializeAsync");
//webView2.CoreWebView2.Navigate("https://www.microsoft.com");
//Debug.WriteLine("after Navigate");
if ((webView2 == null) || (webView2.CoreWebView2 == null))
{
Debug.WriteLine("not ready");
}
webView2.NavigateToString(System.IO.File.ReadAllText("index.html"));
Debug.WriteLine("after NavigateToString");
}
private async Task InitializeAsync()
{
Debug.WriteLine("InitializeAsync");
await webView2.EnsureCoreWebView2Async(null);
Debug.WriteLine("WebView2 Runtime version: " + webView2.CoreWebView2.Environment.BrowserVersionString);
}
private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
Debug.WriteLine("WebView_CoreWebView2InitializationCompleted");
}
Output:
before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after InitializeAsync
after NavigateToString
Update - here's another option
Option 2:
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
webView2.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
Debug.WriteLine("before InitializeAsync");
await InitializeAsync();
Debug.WriteLine("after InitializeAsync");
}
private async Task InitializeAsync()
{
Debug.WriteLine("InitializeAsync");
await webView2.EnsureCoreWebView2Async(null);
Debug.WriteLine("WebView2 Runtime version: " + webView2.CoreWebView2.Environment.BrowserVersionString);
//webView2.CoreWebView2.Navigate("https://www.microsoft.com");
//Debug.WriteLine("after Navigate");
if ((webView2 == null) || (webView2.CoreWebView2 == null))
{
Debug.WriteLine("not ready");
}
webView2.NavigateToString(System.IO.File.ReadAllText("index.html"));
Debug.WriteLine("after NavigateToString");
}
private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
Debug.WriteLine("WebView_CoreWebView2InitializationCompleted");
}
Output:
before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after NavigateToString
after InitializeAsync
User contributions licensed under CC BY-SA 3.0