fix(ui): Worker-Neustart trifft nun den tatsaechlich laufenden Prozess

RestartWorkerService verliess sich auf WorkerLocator.Find(), das bei einem
Debug-Build ohne install.json in der Verzeichniskette auf die Registry
zurueckfaellt und den Pfad der *installierten* Worker.exe liefert. Der
passt nicht zum laufenden Debug-Prozess, also ueberspringt
KillMatchingWorkerProcesses ihn stillschweigend (Pfadvergleich) - der neu
gestartete Worker startet vom falschen Pfad und stirbt sofort am bereits
belegten Port, waehrend der echte Worker unberuehrt weiterlaeuft. Der
Neustart nimmt jetzt den Pfad des tatsaechlich laufenden
ClaudeDo.Worker-Prozesses als Quelle, mit dem Locator nur noch als
Fallback, wenn keiner laeuft.
This commit is contained in:
Mika Kuns
2026-09-16 15:43:36 +02:00
committed by mika kuns
parent 103eb9a687
commit 9a41bed0f5
@@ -657,7 +657,15 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
private void RestartWorkerService()
{
var exe = _workerLocator.Find();
// Prefer the exe path of the worker that's actually running: _workerLocator.Find()
// walks up from AppContext.BaseDirectory looking for install.json and falls back to
// the registry's InstallLocation otherwise — on a debug build launched from the repo
// there's no install.json above it, so it returns the *installed* worker's path. That
// never matches the running debug process, so KillMatchingWorkerProcesses silently
// skips it (it only kills a process whose path equals the given exe) and this either
// launches a second worker that immediately dies on the already-bound port, or leaves
// the real one running untouched while nothing visibly changes.
var exe = RunningWorkerExePath() ?? _workerLocator.Find();
if (exe is null) throw new InvalidOperationException("Worker executable not found.");
KillMatchingWorkerProcesses(exe);
@@ -667,6 +675,20 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
throw new InvalidOperationException($"worker process exited immediately (code {started.ExitCode})");
}
private static string? RunningWorkerExePath()
{
foreach (var p in System.Diagnostics.Process.GetProcessesByName("ClaudeDo.Worker"))
{
try
{
if (p.MainModule?.FileName is { } path) return path;
}
catch { /* inaccessible */ }
finally { p.Dispose(); }
}
return null;
}
// Only kill the worker belonging to THIS installation — not any other
// ClaudeDo.Worker on the machine (e.g. a second install).
private static void KillMatchingWorkerProcesses(string exe)