Files
Hua.Todo/src/Hua.Todo.Maui/Platforms/Windows/WebView2RuntimeDetector.cs
T

100 lines
2.7 KiB
C#

using System.Reflection;
namespace Hua.Todo.Maui.Platforms.Windows;
internal static class WebView2RuntimeDetector
{
/// <summary>
/// 判断当前 Windows 系统是否可用 WebView2 Runtime。
/// 优先通过已知的 Evergreen 安装目录探测(避免因托管程序集缺失/裁剪导致误判),
/// 其次再尝试通过 WebView2 SDK 的 <c>CoreWebView2Environment.GetAvailableBrowserVersionString</c> 获取版本。
/// </summary>
/// <param name="version">检测到的运行时版本(若可用)。</param>
/// <returns>若系统存在可用的 WebView2 Runtime,则返回 <c>true</c>;否则返回 <c>false</c>。</returns>
internal static bool IsRuntimeInstalled(out string? version)
{
version = null;
try
{
version = TryGetEvergreenVersionFromKnownLocations();
if (!string.IsNullOrWhiteSpace(version))
{
return true;
}
var type = Type.GetType("Microsoft.Web.WebView2.Core.CoreWebView2Environment, Microsoft.Web.WebView2.Core");
if (type == null)
{
return false;
}
version = TryInvokeVersionGetter(type);
return !string.IsNullOrWhiteSpace(version);
}
catch
{
return false;
}
}
private static string? TryGetEvergreenVersionFromKnownLocations()
{
var candidates = new[]
{
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft", "EdgeWebView", "Application"),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Microsoft", "EdgeWebView", "Application"),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "EdgeWebView", "Application"),
};
Version? best = null;
foreach (var baseDir in candidates)
{
if (string.IsNullOrWhiteSpace(baseDir) || !Directory.Exists(baseDir))
{
continue;
}
foreach (var dir in Directory.EnumerateDirectories(baseDir))
{
var name = Path.GetFileName(dir);
if (!Version.TryParse(name, out var v))
{
continue;
}
if (!File.Exists(Path.Combine(dir, "msedgewebview2.exe")))
{
continue;
}
if (best == null || v > best)
{
best = v;
}
}
}
return best?.ToString();
}
private static string? TryInvokeVersionGetter(Type environmentType)
{
var noArg = environmentType.GetMethod("GetAvailableBrowserVersionString", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, Type.EmptyTypes, null);
if (noArg != null)
{
return noArg.Invoke(null, null) as string;
}
var oneArg = environmentType.GetMethod("GetAvailableBrowserVersionString", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, new[] { typeof(string) }, null);
if (oneArg != null)
{
return oneArg.Invoke(null, new object?[] { null }) as string;
}
return null;
}
}