mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
Improve launcher startup flow, logging, and host resolution. Key changes: add detailed startup logging and standardized preview messages; unify CLI vs GUI handling and error/result reporting (write result file when requested); refactor DeploymentLocator to a more robust host resolution (new HostResolutionResult, explicit/portable/published/debug resolution paths, legacy fallback); overhaul LauncherFlowCoordinator to better handle IPC stages, activation retries, window lifecycle, plugin/update flows and error reporting; add CommandContext helpers (IsGui/IsPreview/ExplicitAppRoot) and JSON context options; tighten async usage and ConfigureAwait calls; add better UI error handling and consistent exit codes. Several UX/debug conveniences and robustness fixes included.
113 lines
3.2 KiB
C#
113 lines
3.2 KiB
C#
using System.Globalization;
|
|
|
|
namespace LanMountainDesktop.Launcher;
|
|
|
|
internal sealed class CommandContext
|
|
{
|
|
private static readonly string[] GuiCommands =
|
|
[
|
|
"launch",
|
|
"apply-update",
|
|
"preview-splash",
|
|
"preview-error",
|
|
"preview-update",
|
|
"preview-oobe",
|
|
"preview-debug"
|
|
];
|
|
|
|
public string Command { get; }
|
|
|
|
public string SubCommand { get; }
|
|
|
|
public IReadOnlyDictionary<string, string> Options { get; }
|
|
|
|
/// <summary>
|
|
/// 原始命令行参数,用于转发给主程序
|
|
/// </summary>
|
|
public IReadOnlyList<string> RawArgs { get; }
|
|
|
|
public bool IsLegacyPluginInstall =>
|
|
Options.ContainsKey("source") &&
|
|
Options.ContainsKey("plugins-dir") &&
|
|
Options.ContainsKey("result");
|
|
|
|
/// <summary>
|
|
/// 是否处于调试模式(从 Rider/VS 等 IDE 启动)
|
|
/// 仅当明确指定 --debug 参数或调试器附加时才启用
|
|
/// </summary>
|
|
public bool IsDebugMode =>
|
|
Options.ContainsKey("debug") ||
|
|
System.Diagnostics.Debugger.IsAttached;
|
|
|
|
public bool IsPreviewCommand =>
|
|
Command.StartsWith("preview-", StringComparison.OrdinalIgnoreCase);
|
|
|
|
public bool IsGuiCommand =>
|
|
GuiCommands.Contains(Command, StringComparer.OrdinalIgnoreCase);
|
|
|
|
public string? ExplicitAppRoot => GetOption("app-root");
|
|
|
|
private CommandContext(string command, string subCommand, Dictionary<string, string> options, string[] rawArgs)
|
|
{
|
|
Command = command;
|
|
SubCommand = subCommand;
|
|
Options = options;
|
|
RawArgs = rawArgs;
|
|
}
|
|
|
|
public static CommandContext FromArgs(string[] args)
|
|
{
|
|
var options = ParseOptions(args);
|
|
var command = args.Length > 0 && !args[0].StartsWith("--", StringComparison.Ordinal)
|
|
? args[0]
|
|
: "launch";
|
|
var subCommand = args.Length > 1 && !args[1].StartsWith("--", StringComparison.Ordinal)
|
|
? args[1]
|
|
: string.Empty;
|
|
|
|
return new CommandContext(command, subCommand, options, args);
|
|
}
|
|
|
|
public string? GetOption(string key)
|
|
{
|
|
return Options.TryGetValue(key, out var value) ? value : null;
|
|
}
|
|
|
|
public int GetIntOption(string key, int fallback)
|
|
{
|
|
var raw = GetOption(key);
|
|
return int.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)
|
|
? value
|
|
: fallback;
|
|
}
|
|
|
|
private static Dictionary<string, string> ParseOptions(string[] args)
|
|
{
|
|
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
for (var i = 0; i < args.Length; i++)
|
|
{
|
|
var current = args[i];
|
|
if (!current.StartsWith("--", StringComparison.Ordinal))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var key = current[2..];
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (i + 1 < args.Length && !args[i + 1].StartsWith("--", StringComparison.Ordinal))
|
|
{
|
|
values[key] = args[++i];
|
|
continue;
|
|
}
|
|
|
|
values[key] = "true";
|
|
}
|
|
|
|
return values;
|
|
}
|
|
}
|