0

Solution below, thanks to Poul Bak and GrooverFromHolland for pointing out my poor async implementation which helped a bit. I simply moved the source assignment into the same method after the await so order of operations is correct, and also had to first await CoreWebView2Environment.CreateAsync. Not entirely sure why this was necessary from the installed location.

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitWebviewAsync();
        }

private async void InitWebviewAsync()
        {
            var userDataFolder = Setting.ExeShortcutPath + "iGo360UtilitySettingWPF.exe.WebView2";
            var env = await CoreWebView2Environment.CreateAsync(null, userDataFolder);

            if (webView != null)
            {
                await webView.EnsureCoreWebView2Async(env);
                string url = AuthHelper._loginUrl;
                webView.Source = new Uri(url);
            }
        }

Original Issue Posting below:

I currently have a WPF project working perfectly with a WebView2 control while debugging the app with Visual Studio 2019 (16.6.1) with Target .NET Framework 4.6.1.

The following are also installed:

  1. Microsoft Edge WebView2 Runtime (90.0.818.42)
  2. Microsoft Edge (90.0.818.42)

Where I run into a problem is when I install this project via a vdproj and run the application. Note, that this is on the same PC as the debugging environment which seems even more strange.

While writing this issue, I identified the cause to the error I mention further down. Resolving those errors, I copied the following from my debug folder:

  1. runtimes\win-x86\native\WebView2Loader.dll (This resolved the DLLNotFoundException)
  2. iGo360UtilitySettingWPF.exe.WebView2 (This resolved a new error, edge could not write to directory)
  3. What would be the best way to include and manage these 2 directories in a vdproj so not having to manually copy or add them in a hacky way to my project?

Now my current error is on the await line inz InitAsync:

System.Runtime.InteropServices.COMException: 'This operation returned because the timeout period expired. (Exception from HRESULT: 0x800705B4)'

The errors I originally had, but resolved above: As the WebView2 control tries to load, the app crashes. Here's the construct and init methods where it crashes on the await line in InitAsync:

public Login()
{
    string url = AuthHelper._loginUrl;

    InitializeComponent();

    InitAsync();

    if (webView != null)
    {
        webView.Source = new Uri(url);
        //webView.NavigateToString(url);
    }
}

private async void InitAsync()
{
    await webView.EnsureCoreWebView2Async(null);
}

And event viewer logs the following error:

Application: MyWebView2Wpf.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.DllNotFoundException at Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateCoreWebView2EnvironmentWithOptions(System.String, System.String, Microsoft.Web.WebView2.Core.Raw.ICoreWebView2EnvironmentOptions, Microsoft.Web.WebView2.Core.Raw.ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) at Microsoft.Web.WebView2.Core.CoreWebView2Environment+d__3.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task) at Microsoft.Web.WebView2.Wpf.WebView2+<>c__DisplayClass25_0+<g__Init|0>d.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at MyWebView2Wpf.Login+d__4.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object) at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef) at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame) at System.Windows.Application.RunDispatcher(System.Object) at System.Windows.Application.RunInternal(System.Windows.Window) at System.Windows.Application.Run(System.Windows.Window) at System.Windows.Application.Run() at MyWebView2Wpf.App.Main()

Matthew
  • 89
  • 1
  • 8
  • You don't `await` InitAsync(); - that means the code will continue to next line immidiately. – Poul Bak Apr 25 '21 at 14:58
  • Thanks for pointing that out, I have cleaned up the code accordingly. Unfortunately, this did not resolve the issue, but I did stumble onto the problem and fix. Not entirely sure why, but in the installed execution, I needed to specify the webview2 environment directory before the EnsureCoreWebView2Async.... And of course, make sure the Source is being set after the awaiter's have finished. I'll add the updated code in my post for a working solution. – Matthew Apr 25 '21 at 16:09

2 Answers2

2

After InitializeComponent(); you call InitAsync. At that time it is possible that the window or WPF-page is not loaded yet. It is better to initialize it in the Loaded event:"

 private async void Login_Loaded(object sender, RoutedEventArgs e)
        {
            if (webView != null)
            {
                try
                {
                    await webView.EnsureCoreWebView2Async(null);
                    webView.Source = new Uri("https://etc");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
GrooverFromHolland
  • 971
  • 1
  • 11
  • 18
  • Perhaps you are correct, but the problem persists with this adjustment. Still, it works fine while debugging from Visual Studio, but executing this application from installation directory continues to fail. I'm pretty sure the issue revolves around the WebView2 runtime/Edge dependencies, but I'm more or less at a loss. – Matthew Apr 25 '21 at 15:46
2

await CoreWebView2Environment.CreateAsync(null, userDataFolder); was necessary before await webView.EnsureCoreWebView2Async

And ensured webView.Source was being called only after the webView.EnsureCoreWebView2Async finished executing.

Also, made sure the data folder permissions were properly set.

Matthew
  • 89
  • 1
  • 8