feat(service): add ServiceCommands skeleton with platform/admin gates

This commit is contained in:
mika kuns
2026-04-24 19:18:18 +02:00
parent d8f25dc01b
commit 5c6f4b8b6e

View File

@@ -0,0 +1,99 @@
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Security.Principal;
namespace ClaudeMailbox.Cli;
public static class ServiceCommands
{
public const string ServiceName = "ClaudeMailbox";
public static Task<int> RunAsync(string[] args)
{
if (!OperatingSystem.IsWindows())
{
Console.Error.WriteLine("Service commands are Windows-only.");
return Task.FromResult(2);
}
var verb = args[0];
return verb switch
{
"install-service" => Task.FromResult(InstallService(args)),
"uninstall-service" => Task.FromResult(UninstallService(args)),
"start" => Task.FromResult(RunSc("start", ServiceName)),
"stop" => Task.FromResult(RunSc("stop", ServiceName)),
"status" => Task.FromResult(Status()),
_ => Task.FromResult(PrintError($"Unknown service command: {verb}")),
};
}
[SupportedOSPlatform("windows")]
private static bool IsAdministrator()
{
using var identity = WindowsIdentity.GetCurrent();
return new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
}
[SupportedOSPlatform("windows")]
private static int RequireAdmin()
{
if (IsAdministrator()) return 0;
Console.Error.WriteLine("This command requires Administrator privileges.");
return 5;
}
[SupportedOSPlatform("windows")]
private static int InstallService(string[] args)
{
var admin = RequireAdmin();
if (admin != 0) return admin;
Console.Error.WriteLine("install-service: not yet implemented.");
return 1;
}
[SupportedOSPlatform("windows")]
private static int UninstallService(string[] args)
{
var admin = RequireAdmin();
if (admin != 0) return admin;
Console.Error.WriteLine("uninstall-service: not yet implemented.");
return 1;
}
[SupportedOSPlatform("windows")]
private static int Status()
{
Console.Error.WriteLine("status: not yet implemented.");
return 1;
}
[SupportedOSPlatform("windows")]
internal static int RunSc(params string[] scArgs)
{
var psi = new ProcessStartInfo("sc.exe")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
};
foreach (var a in scArgs) psi.ArgumentList.Add(a);
using var proc = Process.Start(psi)!;
var stdout = proc.StandardOutput.ReadToEnd();
var stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit();
if (!string.IsNullOrWhiteSpace(stdout)) Console.Write(stdout);
if (!string.IsNullOrWhiteSpace(stderr)) Console.Error.Write(stderr);
return proc.ExitCode;
}
private static int PrintError(string msg)
{
Console.Error.WriteLine(msg);
return 1;
}
}