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);
|