Files
LanMountainDesktop/LanMountainDesktop.Launcher/Services/LauncherDebugSettingsStore.cs
lincube d4901e436f Add launcher debug settings, recovery & version fixes
Introduce a persistent LauncherDebugSettingsStore and wire it into ErrorWindow and SplashWindow so dev-mode and custom host path can be saved/loaded. Harden DeploymentLocator/FlexibleHostLocator to safely normalize and validate saved debug paths and log warnings for malformed values. Add a WaitingForShell startup state and recoverable-activation logic across App and LauncherFlowCoordinator (with registry updates) so Launcher can attach to an in-progress desktop shell rather than failing. Clean up ErrorDebugWindow UI/flow (WasAccepted flag, localization fixes, event wiring) and improve splash version population. Improve AppVersionProvider to trim surrounding quotes, robustly parse version.json via JsonDocument and read string properties; add unit tests for AppVersionProvider, DeploymentLocator and LauncherDebugSettingsStore. Also quote Exec commands in the csproj and harden scripts/Generate-VersionFile.ps1 (argument normalization, LiteralPath, error handling).
2026-04-23 19:04:39 +08:00

125 lines
3.9 KiB
C#

namespace LanMountainDesktop.Launcher.Services;
internal sealed record LauncherDebugSettings(bool DevModeEnabled, string? CustomHostPath);
internal static class LauncherDebugSettingsStore
{
private const string DevModeFileName = "dev-mode.flag";
private const string CustomHostPathFileName = "custom-host-path.txt";
private const string LegacyDevModeFileName = "devmode.config";
private const string LegacyCustomHostPathFileName = "custom-host-path.config";
internal static string? ConfigBaseDirectoryOverride { get; set; }
public static string ConfigBaseDirectory => ConfigBaseDirectoryOverride ?? ResolveConfigBaseDirectory();
public static LauncherDebugSettings Load()
{
return new LauncherDebugSettings(
LoadDevModeState(),
LoadCustomHostPath());
}
public static bool IsDevModeEnabled() => Load().DevModeEnabled;
public static string? GetSavedCustomHostPath() => Load().CustomHostPath;
public static void Save(LauncherDebugSettings settings)
{
try
{
Directory.CreateDirectory(ConfigBaseDirectory);
File.WriteAllText(GetPath(DevModeFileName), settings.DevModeEnabled.ToString());
File.WriteAllText(GetPath(CustomHostPathFileName), settings.CustomHostPath ?? string.Empty);
}
catch (Exception ex)
{
Logger.Warn($"Failed to save launcher debug settings: {ex.Message}");
}
}
public static void SaveDevModeState(bool enabled)
{
var current = Load();
Save(current with { DevModeEnabled = enabled });
}
public static void SaveCustomHostPath(string? customHostPath)
{
var current = Load();
Save(current with { CustomHostPath = customHostPath });
}
private static bool LoadDevModeState()
{
var newValue = TryReadText(GetPath(DevModeFileName));
if (!string.IsNullOrWhiteSpace(newValue))
{
return TryParseDevMode(newValue);
}
var legacyValue = TryReadText(GetPath(LegacyDevModeFileName));
return !string.IsNullOrWhiteSpace(legacyValue) && TryParseDevMode(legacyValue);
}
private static string? LoadCustomHostPath()
{
var newValue = TryReadText(GetPath(CustomHostPathFileName));
if (!string.IsNullOrWhiteSpace(newValue))
{
return newValue.Trim();
}
var legacyValue = TryReadText(GetPath(LegacyCustomHostPathFileName));
return string.IsNullOrWhiteSpace(legacyValue) ? null : legacyValue.Trim();
}
private static bool TryParseDevMode(string value)
{
var normalized = value.Trim();
return normalized == "1" ||
normalized.Equals("true", StringComparison.OrdinalIgnoreCase) ||
normalized.Equals("yes", StringComparison.OrdinalIgnoreCase) ||
normalized.Equals("on", StringComparison.OrdinalIgnoreCase);
}
private static string? TryReadText(string path)
{
try
{
return File.Exists(path) ? File.ReadAllText(path) : null;
}
catch (Exception ex)
{
Logger.Warn($"Failed to read launcher debug setting '{path}': {ex.Message}");
return null;
}
}
private static string GetPath(string fileName) => Path.Combine(ConfigBaseDirectory, fileName);
private static string ResolveConfigBaseDirectory()
{
try
{
var appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (!string.IsNullOrWhiteSpace(appData))
{
return Path.Combine(appData, "LanMountainDesktop", ".launcher");
}
}
catch
{
}
try
{
return Path.Combine(AppContext.BaseDirectory, ".launcher");
}
catch
{
return Path.Combine(Directory.GetCurrentDirectory(), ".launcher");
}
}
}