Files
LanMountainDesktop/LanMountainDesktop/Services/WebView2RuntimeProbe.cs
lincube abfa64b3d7 Avalonia12 (#7)
* ava12升级

* Enable centralized package versioning

Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files.

* Migrate codebase to Avalonia 12 APIs

Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing.

* Migrate to Avalonia 12 and Plugin SDK v5

Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md.

Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility.

* Update icon glyphs and symbol mappings

Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources.

* fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00

135 lines
4.3 KiB
C#

using System;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using Microsoft.Win32;
namespace LanMountainDesktop.Services;
public sealed record WebView2RuntimeAvailability(
bool IsAvailable,
string? Version,
string Message);
public static class WebView2RuntimeProbe
{
private const string WebView2RuntimeClientId = "{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}";
private const string WebView2RuntimeKeyPath = @"SOFTWARE\Microsoft\EdgeUpdate\Clients\" + WebView2RuntimeClientId;
public const string RuntimeDownloadUrl = "https://go.microsoft.com/fwlink/p/?LinkId=2124703";
public static WebView2RuntimeAvailability GetAvailability()
{
if (OperatingSystem.IsMacOS())
{
return new WebView2RuntimeAvailability(
IsAvailable: true,
Version: null,
Message: string.Empty);
}
if (!OperatingSystem.IsWindows())
{
return new WebView2RuntimeAvailability(
IsAvailable: false,
Version: null,
Message: "Embedded browser is currently unavailable on this platform.");
}
try
{
var version = TryGetVersionFromWebView2Api();
if (string.IsNullOrWhiteSpace(version))
{
version = TryGetVersionFromRegistry();
}
if (!string.IsNullOrWhiteSpace(version))
{
return new WebView2RuntimeAvailability(
IsAvailable: true,
Version: version.Trim(),
Message: string.Empty);
}
return new WebView2RuntimeAvailability(
IsAvailable: false,
Version: null,
Message: $"WebView2 Runtime is missing. Install it from {RuntimeDownloadUrl} and restart the app.");
}
catch (Exception ex)
{
return new WebView2RuntimeAvailability(
IsAvailable: false,
Version: null,
Message: $"WebView2 runtime check failed: {ex.Message}");
}
}
public static string ResolveUserDataFolder()
{
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (string.IsNullOrWhiteSpace(localAppData))
{
localAppData = AppContext.BaseDirectory;
}
var userDataFolder = Path.Combine(localAppData, "LanMountainDesktop", "WebView2");
Directory.CreateDirectory(userDataFolder);
return userDataFolder;
}
private static string? TryGetVersionFromWebView2Api()
{
var type = Type.GetType(
"Microsoft.Web.WebView2.Core.CoreWebView2Environment, Microsoft.Web.WebView2.Core",
throwOnError: false);
if (type is null)
{
return null;
}
var method = type.GetMethod(
"GetAvailableBrowserVersionString",
BindingFlags.Public | BindingFlags.Static,
binder: null,
types: Type.EmptyTypes,
modifiers: null);
if (method is null)
{
return null;
}
return method.Invoke(null, null) as string;
}
[SupportedOSPlatform("windows")]
private static string? TryGetVersionFromRegistry()
{
return TryReadVersionFromRegistry(RegistryHive.LocalMachine, RegistryView.Registry64)
?? TryReadVersionFromRegistry(RegistryHive.LocalMachine, RegistryView.Registry32)
?? TryReadVersionFromRegistry(RegistryHive.CurrentUser, RegistryView.Registry64)
?? TryReadVersionFromRegistry(RegistryHive.CurrentUser, RegistryView.Registry32);
}
[SupportedOSPlatform("windows")]
private static string? TryReadVersionFromRegistry(RegistryHive hive, RegistryView view)
{
try
{
using var baseKey = RegistryKey.OpenBaseKey(hive, view);
using var runtimeKey = baseKey.OpenSubKey(WebView2RuntimeKeyPath, writable: false);
if (runtimeKey is null)
{
return null;
}
var value = runtimeKey.GetValue("pv") as string;
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
catch
{
return null;
}
}
}