Files
RhythmicWallpaper/AudioVisualizer/SSO/WebView2Browser.cs

102 lines
3.5 KiB
C#

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<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default) {
var tcs = new TaskCompletionSource<BrowserResult>();
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;
}
}
}