Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeout Exception when CoreWebView2 initialization #2888

Closed
KianZhou8005 opened this issue Oct 18, 2022 · 8 comments
Closed

Timeout Exception when CoreWebView2 initialization #2888

KianZhou8005 opened this issue Oct 18, 2022 · 8 comments
Assignees

Comments

@KianZhou8005
Copy link

KianZhou8005 commented Oct 18, 2022

Description:

There are already some webview2 instances(run it by windows user A) running in my server. They work fine.
Now I deploy a new webview2 app and run it by user B. When the coreWebView2 is initializing, I get the Timeout exception. But if I run it by user A, it works fine.
Could you give some advises? or is there any way to get more internal logs?

I noted the #2054 . In my app, the userDataFolder is different for each WebView2 instance, so I think it maybe different case.

Here is my code:

            public async void InitializeWebView2Async()
        {
            webView2 = new WebView2();
            var runtimePath = RuntimePath;
            var userDataFolder = UserDataFolderLocation + Environment.UserName + DateTime.Now.Ticks;
            var options = new CoreWebView2EnvironmentOptions
            {
                AdditionalBrowserArguments = "--disable-web-security --no-proxy-server --disable-pinch --ignore-gpu-blocklist --enable-webgl --enable-gpu",
                Language = Thread.CurrentThread.CurrentUICulture.Name,
            };
            var env = await CoreWebView2Environment.CreateAsync(runtimePath, userDataFolder, options);
            webView2.CoreWebView2InitializationCompleted += CoreWebView2InitializationCompleted;
            await webView2.EnsureCoreWebView2Async(env);
        }

private async void CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            if (e.IsSuccess)
            {
                //some codes
            }
            else
            {
                Log.Error("Failed to initialize CoreWebView2", e.InitializationException);
            }
        }

Exception:

System.Runtime.InteropServices.COMException (0x800705B4): This operation returned because the timeout period expired. (Exception from HRESULT: 0x800705B4)
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at Microsoft.Web.WebView2.Core.CoreWebView2Environment.<CreateCoreWebView2ControllerAsync>d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Web.WebView2.Wpf.WebView2.<>c__DisplayClass27_0.<<EnsureCoreWebView2Async>g__Init|0>d.MoveNext()

Version:

Microsoft SDK Version: 1.0.1020.30
Microsoft RT Version: 95.0.1020.53

@LiangTheDev
Copy link
Member

One way WebView2 initialization could time out is if the control is not in WPF UI tree. Could you try to ensure that the control is added into the UI (it could still be not really visible to the user) and see whether that makes it to work?

@KianZhou8005
Copy link
Author

I think it should be added into the UI tree, because I can see the website loaded successfully if I run it by Windows user A. it only throw timeout exception when I run it by Windows user B.

Here is the code that I add it into the UI tree.
Xaml:

<Grid x:Name="Layout">
            <ContentPresenter Content="{Binding Content}" />
</Grid>

ViewModel:

public class BrowserViewModel : ViewModelBase
    {
        private readonly IBrowserService browserService;
        private string uri;
        private object content;

        public BrowserViewModel(IBrowserService browserService)
        {
            this.browserService = browserService;
            content = browserService.Browser; // Browser gets webView2 instance created in InitializeWebView2Async() 
            uri = browserService.CurrentUri;
        }
}

@LiangTheDev
Copy link
Member

From the code shared in your initial post, I see that you are creating a new WebView with webView2 = new WebView2();, and I don't see code adding that control into UI tree.

Do you see any files created under the specified user data folder? If there are some files created, then it means that we started WebView initialization. Otherwise, we are waiting for something else. The only thing I can see that we wait before start processing for the control to be in UI tree so that we can have the parent hwnd for the WebView2.

@KianZhou8005
Copy link
Author

KianZhou8005 commented Oct 21, 2022

Do you see any files created under the specified user data folder?

Yes, there is folder called 'EBWebVew' created under the user data folder, and there are many subfolders under the 'EBWebVew'

From the code shared in your initial post, I see that you are creating a new WebView with webView2 = new WebView2();, and > I don't see code adding that control into UI tree.

Sorry for showing incomplete code, here is my full code about WebView2 Initialization:

Interface:

 public interface IBrowserService
    {
        string CurrentUri { get; }
        object Browser { get; }
}

Service:

public class WebView2Service : IBrowserService
    {
        private static readonly ILogger Log = MrLogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private string currentUri;
        private WebView2 webView2;
        private const string UserDataFolderLocation = "C:\\Temp\\WebView2 Runtime Fixed ";

        public WebView2Service(string uri)
        {
            this.currentUri = uri;
            InitializeWebView2Async();
        }

        public event EventHandler<NavigationCompletedEventArgs> NavigationCompleted;

        public string CurrentUri { get => currentUri; }
        public object Browser { get => webView2; }

        public async void InitializeWebView2Async()
        {
            webView2 = new WebView2();
            var runtimePath = Common.RuntimePath;
            var userDataFolder = UserDataFolderLocation + Environment.UserName + DateTime.Now.Ticks;
            var options = new CoreWebView2EnvironmentOptions
            {
                AdditionalBrowserArguments = "--disable-web-security --no-proxy-server --disable-pinch --ignore-gpu-blocklist --enable-webgl --enable-gpu",
                Language = Thread.CurrentThread.CurrentUICulture.Name,
            };
            var env = await CoreWebView2Environment.CreateAsync(runtimePath, userDataFolder, options);
            webView2.CoreWebView2InitializationCompleted += CoreWebView2InitializationCompleted;
            await webView2.EnsureCoreWebView2Async(env);
        }

        private async void CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            if (e.IsSuccess)
            {
                Log.Info("CoreWebView2 was successfully initialized");
                webView2.CoreWebView2.Navigate(currentUri);
            }
            else
            {
                Log.Error("Failed to initialize CoreWebView2", e.InitializationException);
            }
        }
}

ViewModel:

public class BrowserViewModel : ViewModelBase
    {
        private readonly IBrowserService browserService;
        private string uri;
        private object content;

        public BrowserViewModel(IBrowserService browserService)
        {
            this.browserService = browserService;
            content = browserService.Browser; 
            uri = browserService.CurrentUri;
        }
}

App.xaml.cs

public partial class App : Application
    {
        private static readonly ILogger Log = MrLogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        protected override void OnStartup(StartupEventArgs e)
        {
            StartUp(e);
        }

        private void StartUp(StartupEventArgs e)
        {
            if (e.Args.Length == 1)
            {
                try
                {
                    var startupUrl = e.Args[0];
                    var service = new WebView2Service(startupUrl);
                    var viewModel = new BrowserViewModel(service);
                    MainWindow = new MainWindow { DataContext = viewModel };
                    MainWindow.Show();
                }
                catch (Exception ex)
                {
                    Log.Error("Failed to initialize", ex);
                    Console.WriteLine("Initialization Failed" + ex.Message);
                    Shutdown();
                }
            }
            else
            {
                Console.WriteLine("WebBrowser.exe [URL]");
                Shutdown();
            }
        }
}

MainWindow.xaml.cs

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

@LiangTheDev
Copy link
Member

Could you take a performance trace for the repro for triage? How to take the performance trace: #1540 (comment). As the resulted etl file could be large, please share it via some cloud drive.

As the latest Edge WebView2 Runtime logs more event, if you could get a trace with the latest runtime, that would be even more helpful.

The fact that there are files created under the EBWebView folder, and you didn't mention that you have to wait for a long time to get the timeout error thrown, suggest that it is something else.

@KianZhou8005
Copy link
Author

Sorry, I am not able to take the performance trace as the server is for internal use.

I will try to get the latest runtime to see if it is helpful.

The fact that there are files created under the EBWebView folder, and you didn't mention that you have to wait for a long time to get the timeout error thrown, suggest that it is something else.

In fact, I have to wait for long time (around 2 mins) to get the timeout error.

@LiangTheDev
Copy link
Member

So, it is really a timeout. Without a trace, I'll have to brainstorm.
Is there any crash dump file (*.dmp) under EBWebView\Crashpad\reports subfolder of the specified user data folder?
Any events in event viewer?
Is it possible that there are some policy/antivirus produce on the device that blocks msedgewebview2.exe process from being created by the app?

@KianZhou8005
Copy link
Author

The webview2 initialization works fine after I upgraded the runtime version to 104.0.1293.54. it seems the new runtime version solve this issue, that is great!

Thank you for you help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants