using IdentityModel.OidcClient.Browser; using Microsoft.Web.WebView2.WinForms; using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace AudioWallpaper.SSO { public class WebView2Browser : IBrowser { private readonly int _windowWidth; private readonly int _windowHeight; private readonly Form? _form; public WebView2Browser(int width = 600, int height = 800) { _windowWidth = width; _windowHeight = height; } public WebView2Browser(Form form, int width = 600, int height = 800) { _windowWidth = width; _windowHeight = height; _form = form; } public WebView2Browser(Form form) { _windowWidth = 600; _windowHeight = 800; _form = form; } public Task InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default) { var tcs = new TaskCompletionSource(); var thread = new Thread(() => { var form = new Form { Width = _windowWidth, Height = _windowHeight, StartPosition = FormStartPosition.CenterScreen, Text = "登录认证" }; var webView = new WebView2 { Dock = DockStyle.Fill }; form.Controls.Add(webView); form.FormClosed += (s, e) => { if (!tcs.Task.IsCompleted) { tcs.TrySetResult(new BrowserResult { ResultType = BrowserResultType.UserCancel, Error = "User closed the login window" }); } }; webView.NavigationStarting += (s, e) => { if (e.Uri.StartsWith(options.EndUrl)) { tcs.TrySetResult(new BrowserResult { ResultType = BrowserResultType.Success, Response = e.Uri }); form.Invoke(new Action(() => form.Close())); } }; webView.CoreWebView2InitializationCompleted += async (s, e) => { if (e.IsSuccess) { webView.CoreWebView2.Settings.AreDevToolsEnabled = false; webView.CoreWebView2.ContextMenuRequested += (s, e) => { e.Handled = true; }; webView.CoreWebView2.Navigate(options.StartUrl); } else { tcs.TrySetResult(new BrowserResult { ResultType = BrowserResultType.UnknownError, Error = "WebView2 initialization failed" }); form.Close(); } }; form.Load += async (s, e) => { await webView.EnsureCoreWebView2Async(null); }; if (_form != null) { _form.Invoke(new Action(() => { form.ShowDialog(_form); })); } else { Application.Run(form); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); return tcs.Task; } } }