feat(ui): add Restart worker menu entry under Help

Stops and starts the ClaudeDoWorker Windows service via
ServiceController. SignalR auto-reconnect plus the existing
ConnectionRestoredEvent handle the refresh, so the UI repopulates
counters and the active list once the worker is back up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-05-18 16:39:40 +02:00
parent 0d55002e5e
commit 8d34db3f9b
3 changed files with 48 additions and 0 deletions

View File

@@ -255,6 +255,51 @@ public sealed partial class IslandsShellViewModel : ViewModelBase
await _updateCheck.CheckNowAsync(CancellationToken.None);
}
[ObservableProperty] private string? _restartWorkerStatus;
[RelayCommand]
private async Task RestartWorkerAsync()
{
if (!OperatingSystem.IsWindows())
{
await FlashRestartStatusAsync("Service control is Windows-only.");
return;
}
RestartWorkerStatus = "Restarting worker…";
try
{
await Task.Run(() =>
{
using var sc = new System.ServiceProcess.ServiceController("ClaudeDoWorker");
if (sc.Status != System.ServiceProcess.ServiceControllerStatus.Stopped)
{
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(20));
}
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, TimeSpan.FromSeconds(20));
});
await FlashRestartStatusAsync("Worker restarted.");
}
catch (InvalidOperationException)
{
// ServiceController throws this when the service is not installed.
await FlashRestartStatusAsync("ClaudeDoWorker service is not installed.");
}
catch (Exception ex)
{
await FlashRestartStatusAsync($"Restart failed: {ex.Message}");
}
}
private async Task FlashRestartStatusAsync(string text)
{
RestartWorkerStatus = text;
await Task.Delay(3000);
if (RestartWorkerStatus == text) RestartWorkerStatus = null;
}
[RelayCommand]
private void DismissBanner()
{