WorkerConnectionModalViewModel's StartWorker/RerunInstaller swallowed missing-exe and Process.Start failures behind an empty catch and closed the dialog anyway, looking like success. Now both show an inline error and keep the dialog open; only a real launch closes it. IslandsShellViewModel.RestartWorkerAsync never checked whether the relaunched worker actually stayed up, and its status property was never bound in any view. RestartWorkerService now fails if the new process exits within a short survival window, and the outcome routes through the footer error/success strip instead of the dead RestartWorkerStatus. InstallArtifactLocator.Find() is now virtual and its two subclasses unsealed so tests can fake exe resolution without touching the real filesystem/registry.
54 lines
1.9 KiB
C#
54 lines
1.9 KiB
C#
namespace ClaudeDo.Ui.Services;
|
|
|
|
// Two named types because DI resolves them by type, not by key. Not sealed: tests subclass
|
|
// these to fake Find() without touching the real filesystem/registry.
|
|
public class InstallerLocator() : InstallArtifactLocator("uninstaller", "ClaudeDo.Installer.exe");
|
|
|
|
public class WorkerLocator() : InstallArtifactLocator("worker", "ClaudeDo.Worker.exe");
|
|
|
|
/// <summary>
|
|
/// Locates an executable inside a ClaudeDo install: walk up from the running
|
|
/// directory to the folder containing install.json, otherwise read the
|
|
/// uninstall registry key (which is what makes this work from a dev build).
|
|
/// </summary>
|
|
public abstract class InstallArtifactLocator(string subdir, string exeName)
|
|
{
|
|
private const string InstallJson = "install.json";
|
|
|
|
public virtual string? Find()
|
|
=> FindByWalkingUp(AppContext.BaseDirectory)
|
|
?? (OperatingSystem.IsWindows() ? FindByRegistry() : null);
|
|
|
|
public string? FindByWalkingUp(string startDir)
|
|
{
|
|
var dir = new DirectoryInfo(startDir);
|
|
while (dir is not null)
|
|
{
|
|
if (File.Exists(Path.Combine(dir.FullName, InstallJson)))
|
|
return Candidate(dir.FullName);
|
|
dir = dir.Parent;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
|
|
public string? FindByRegistry()
|
|
{
|
|
if (!OperatingSystem.IsWindows()) return null;
|
|
try
|
|
{
|
|
using var key = Microsoft.Win32.Registry.LocalMachine
|
|
.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\ClaudeDo");
|
|
var location = key?.GetValue("InstallLocation") as string;
|
|
return string.IsNullOrEmpty(location) ? null : Candidate(location);
|
|
}
|
|
catch { return null; }
|
|
}
|
|
|
|
private string? Candidate(string installDir)
|
|
{
|
|
var path = Path.Combine(installDir, subdir, exeName);
|
|
return File.Exists(path) ? path : null;
|
|
}
|
|
}
|