mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
185 lines
6.8 KiB
C#
185 lines
6.8 KiB
C#
using System.Text.Json;
|
||
using System.Text.Json.Nodes;
|
||
using LanMountainDesktop.Shared.Contracts.Launcher;
|
||
|
||
namespace LanMountainDesktop.Launcher.Services;
|
||
|
||
/// <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);
|