Files
LanMountainDesktop/LanMountainDesktop.Launcher/Oobe/HostAppSettingsOobeMerger.cs
2026-05-28 10:43:30 +08:00

185 lines
6.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text.Json;
using System.Text.Json.Nodes;
using LanMountainDesktop.Shared.Contracts.Launcher;
namespace LanMountainDesktop.Launcher.Oobe;
/// <summary>
/// 在 OOBE 中向 Host 的 settings.json 写入启动与展示相关字段,属性名与 Host
/// AppSettingsSnapshot 的 JSON 序列化一致PascalCase
/// </summary>
public static class HostAppSettingsOobeMerger
{
public const string ShowInTaskbarKey = "ShowInTaskbar";
public const string EnableFadeTransitionKey = "EnableFadeTransition";
public const string EnableSlideTransitionKey = "EnableSlideTransition";
public const string EnableFusedDesktopKey = "EnableFusedDesktop";
public const string EnableThreeFingerSwipeKey = "EnableThreeFingerSwipe";
public const string AutoStartWithWindowsKey = "AutoStartWithWindows";
public const string MultiInstanceLaunchBehaviorKey = "MultiInstanceLaunchBehavior";
public static string GetSettingsFilePath(string dataRoot) =>
Path.Combine(Path.GetFullPath(dataRoot.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)), "settings.json");
public static HostAppSettingsStartupDefaults LoadStartupDefaults(string settingsPath)
{
if (!File.Exists(settingsPath))
{
return HostAppSettingsStartupDefaults.Fallback;
}
try
{
var root = JsonNode.Parse(File.ReadAllText(settingsPath))?.AsObject();
if (root is null)
{
return HostAppSettingsStartupDefaults.Fallback;
}
var fade = ReadBool(root, EnableFadeTransitionKey, defaultValue: true);
var slide = ReadBool(root, EnableSlideTransitionKey, defaultValue: false);
var normalized = StartupVisualPreferencesResolver.FromFlags(fade, slide);
return new HostAppSettingsStartupDefaults(
ShowInTaskbar: ReadBool(root, ShowInTaskbarKey, defaultValue: false),
EnableFadeTransition: normalized.EnableFadeTransition,
EnableSlideTransition: normalized.EnableSlideTransition,
FusedPopupExperience: ReadBool(root, EnableFusedDesktopKey, defaultValue: false) &&
ReadBool(root, EnableThreeFingerSwipeKey, defaultValue: false),
AutoStartWithWindows: ReadBool(root, AutoStartWithWindowsKey, defaultValue: false));
}
catch (Exception ex)
{
Logger.Warn($"HostAppSettingsOobeMerger: failed to read '{settingsPath}'. {ex.Message}");
return HostAppSettingsStartupDefaults.Fallback;
}
}
public static MultiInstanceLaunchBehavior LoadMultiInstanceLaunchBehavior(string settingsPath)
{
if (!File.Exists(settingsPath))
{
return MultiInstanceLaunchBehavior.NotifyAndOpenDesktop;
}
try
{
var root = JsonNode.Parse(File.ReadAllText(settingsPath))?.AsObject();
if (root is null)
{
return MultiInstanceLaunchBehavior.NotifyAndOpenDesktop;
}
return ReadMultiInstanceLaunchBehavior(root);
}
catch (Exception ex)
{
Logger.Warn($"HostAppSettingsOobeMerger: failed to read multi-instance behavior from '{settingsPath}'. {ex.Message}");
return MultiInstanceLaunchBehavior.NotifyAndOpenDesktop;
}
}
public static void MergeStartupPresentation(string settingsPath, HostAppSettingsStartupChoices choices)
{
var directory = Path.GetDirectoryName(settingsPath);
if (!string.IsNullOrWhiteSpace(directory))
{
Directory.CreateDirectory(directory);
}
JsonObject root;
if (File.Exists(settingsPath))
{
try
{
root = JsonNode.Parse(File.ReadAllText(settingsPath))?.AsObject() ?? new JsonObject();
}
catch (Exception ex)
{
Logger.Warn($"HostAppSettingsOobeMerger: replacing invalid JSON at '{settingsPath}'. {ex.Message}");
root = new JsonObject();
}
}
else
{
root = new JsonObject();
}
var normalized = StartupVisualPreferencesResolver.FromFlags(
choices.EnableFadeTransition,
choices.EnableSlideTransition);
root[ShowInTaskbarKey] = choices.ShowInTaskbar;
root[EnableFadeTransitionKey] = normalized.EnableFadeTransition;
root[EnableSlideTransitionKey] = normalized.EnableSlideTransition;
root[EnableFusedDesktopKey] = choices.FusedPopupExperience;
root[EnableThreeFingerSwipeKey] = choices.FusedPopupExperience;
root[AutoStartWithWindowsKey] = choices.AutoStartWithWindows;
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(settingsPath, root.ToJsonString(options));
}
private static bool ReadBool(JsonObject root, string key, bool defaultValue)
{
if (!root.TryGetPropertyValue(key, out var node) || node is null)
{
return defaultValue;
}
return node switch
{
JsonValue v when v.TryGetValue<bool>(out var b) => b,
JsonValue v when v.TryGetValue<string>(out var s) => bool.TryParse(s, out var p) && p,
_ => defaultValue
};
}
private static MultiInstanceLaunchBehavior ReadMultiInstanceLaunchBehavior(JsonObject root)
{
if (!root.TryGetPropertyValue(MultiInstanceLaunchBehaviorKey, out var node) || node is null)
{
return MultiInstanceLaunchBehavior.NotifyAndOpenDesktop;
}
if (node is JsonValue value)
{
if (value.TryGetValue<string>(out var text) &&
Enum.TryParse<MultiInstanceLaunchBehavior>(text, ignoreCase: true, out var parsed))
{
return parsed;
}
if (value.TryGetValue<int>(out var numeric) &&
Enum.IsDefined(typeof(MultiInstanceLaunchBehavior), numeric))
{
return (MultiInstanceLaunchBehavior)numeric;
}
}
return MultiInstanceLaunchBehavior.NotifyAndOpenDesktop;
}
}
public readonly record struct HostAppSettingsStartupDefaults(
bool ShowInTaskbar,
bool EnableFadeTransition,
bool EnableSlideTransition,
bool FusedPopupExperience,
bool AutoStartWithWindows)
{
public static HostAppSettingsStartupDefaults Fallback { get; } = new(
ShowInTaskbar: false,
EnableFadeTransition: true,
EnableSlideTransition: false,
FusedPopupExperience: false,
AutoStartWithWindows: false);
}
public readonly record struct HostAppSettingsStartupChoices(
bool ShowInTaskbar,
bool EnableFadeTransition,
bool EnableSlideTransition,
bool FusedPopupExperience,
bool AutoStartWithWindows);