52 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|