2026-04-16 01:59:21 +08:00
|
|
|
using System.Globalization;
|
|
|
|
|
|
|
|
|
|
namespace LanMountainDesktop.Launcher;
|
|
|
|
|
|
|
|
|
|
internal sealed class CommandContext
|
|
|
|
|
{
|
|
|
|
|
public string Command { get; }
|
|
|
|
|
|
|
|
|
|
public string SubCommand { get; }
|
|
|
|
|
|
|
|
|
|
public IReadOnlyDictionary<string, string> Options { get; }
|
|
|
|
|
|
2026-04-17 15:16:01 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 原始命令行参数,用于转发给主程序
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IReadOnlyList<string> RawArgs { get; }
|
|
|
|
|
|
2026-04-16 01:59:21 +08:00
|
|
|
public bool IsLegacyPluginInstall =>
|
|
|
|
|
Options.ContainsKey("source") &&
|
|
|
|
|
Options.ContainsKey("plugins-dir") &&
|
|
|
|
|
Options.ContainsKey("result");
|
|
|
|
|
|
2026-04-17 15:16:01 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 是否处于调试模式(从 Rider/VS 等 IDE 启动)
|
|
|
|
|
/// 仅当明确指定 --debug 参数或调试器附加时才启用
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool IsDebugMode =>
|
|
|
|
|
Options.ContainsKey("debug") ||
|
|
|
|
|
System.Diagnostics.Debugger.IsAttached;
|
|
|
|
|
|
|
|
|
|
private CommandContext(string command, string subCommand, Dictionary<string, string> options, string[] rawArgs)
|
2026-04-16 01:59:21 +08:00
|
|
|
{
|
|
|
|
|
Command = command;
|
|
|
|
|
SubCommand = subCommand;
|
|
|
|
|
Options = options;
|
2026-04-17 15:16:01 +08:00
|
|
|
RawArgs = rawArgs;
|
2026-04-16 01:59:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2026-04-17 15:16:01 +08:00
|
|
|
return new CommandContext(command, subCommand, options, args);
|
2026-04-16 01:59:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|