Files
Gateway-keepaliveForDotnet/src/GatewayKeepalive.Windows/DiagnosticCommands.cs
T
chuzhongzai 2d85527656 实现 .NET 10 托盘版网关保活
包含分层探测、可补偿的 IPv4 路由/DNS 切换、自动策略、托盘与分组设置界面、只读诊断工具、离线测试和发布脚本。
2026-10-23 23:35:20 +08:00

52 lines
3.2 KiB
C#

using System.Text.Json;
using GatewayKeepalive.Core;
namespace GatewayKeepalive.Windows;
public static class DiagnosticCommands
{
public static async Task<int> RunAsync(string[] args)
{
string? Value(string name) { var i = Array.IndexOf(args, name); return i >= 0 && i + 1 < args.Length ? args[i + 1] : null; }
object report;
var exitCode = 0;
try
{
var backend = new WindowsNetworkBackend();
var adapters = await backend.ListAdaptersAsync(CancellationToken.None);
var settingsPath = Value("--config") ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "GatewayKeepalive", "settings.json");
var settings = File.Exists(settingsPath) ? JsonSerializer.Deserialize<AppSettings>(File.ReadAllText(settingsPath), JsonStore.Options) ?? throw new InvalidDataException("配置为空。") : new();
if (Value("--adapter") is { } adapter) settings = settings with { AdapterId = Guid.Parse(adapter), Configured = true };
backend.ConfigureIdentity(settings);
var snapshots = new List<object>();
foreach (var item in adapters.Where(x => settings.AdapterId == Guid.Empty || x.Id == settings.AdapterId))
{
try { snapshots.Add(await backend.CaptureAsync(item.Id, CancellationToken.None)); }
catch (Exception e) { snapshots.Add(new { Adapter = item, Error = e.Message }); }
}
object? plan = null;
HealthReport? health = null;
if (args.Contains("--dry-run") || args.Contains("--probe"))
{
settings.Validate();
var snapshot = await backend.CaptureAsync(settings.AdapterId, CancellationToken.None);
var probe = new NetworkHealthProbe(backend.ValidateRoute);
if (args.Contains("--probe")) health = await probe.CheckAsync(settings, snapshot, CancellationToken.None);
if (args.Contains("--dry-run"))
{
var service = new SwitchService(backend, probe, new JsonStore(Path.GetDirectoryName(settingsPath)!), _ => { });
plan = service.Plan(settings, snapshot, !args.Contains("--direct"), snapshot.Gateway == settings.DirectGateway && settings.PreserveOriginalDirectDns ? snapshot.Dns : null);
}
}
object? bestRoute;
try { bestRoute = backend.DescribeBestRoute("1.1.1.1"); } catch (Exception e) { bestRoute = new { Error = e.Message }; }
report = new { ReadOnly = true, IsAdministrator = backend.IsAdministrator, NativeLayout = WindowsNetworkBackend.NativeLayout(), Adapters = adapters, Snapshots = snapshots, BestRoute = bestRoute, PlannedConfiguration = plan, Health = health };
}
catch (Exception e) { report = new { ReadOnly = true, Error = e.Message, Diagnostic = args.Contains("--verbose") ? e.ToString() : null }; exitCode = 1; }
var json = JsonSerializer.Serialize(report, JsonStore.Options);
if (Value("--output") is { } path) { Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path))!); await File.WriteAllTextAsync(path, json); }
Console.WriteLine(json);
return exitCode;
}
}