feat(installer): add UninstallRunner (service + shortcuts + dirs)

This commit is contained in:
Mika Kuns
2026-04-15 10:29:25 +02:00
parent 8d2f7e9907
commit ac38ea8c34
2 changed files with 71 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
using System.IO;
using ClaudeDo.Data;
using ClaudeDo.Installer.Steps;
namespace ClaudeDo.Installer.Core;
public sealed class UninstallRunner
{
private readonly InstallContext _context;
private readonly StopServiceStep _stopService;
public UninstallRunner(InstallContext context, StopServiceStep stopService)
{
_context = context;
_stopService = stopService;
}
public async Task<StepResult> RunAsync(IProgress<string> progress, CancellationToken ct)
{
// 1) Stop + delete service.
progress.Report("Stopping worker service...");
var stopResult = await _stopService.ExecuteAsync(_context, progress, ct);
if (!stopResult.Success)
{
progress.Report($"(Ignored) {stopResult.ErrorMessage}");
}
progress.Report("Unregistering service...");
await ProcessRunner.RunAsync("sc.exe", $"delete {StopServiceStep.ServiceName}", null, progress, ct);
// 2) Remove shortcuts.
progress.Report("Removing shortcuts...");
TryDeleteFile(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory),
"ClaudeDo.lnk"));
TryDeleteFile(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu),
"Programs", "ClaudeDo.lnk"));
// 3) Delete install directory.
if (Directory.Exists(_context.InstallDirectory))
{
progress.Report($"Deleting {_context.InstallDirectory}...");
TryDeleteDir(_context.InstallDirectory);
}
// 4) Delete ~/.todo-app (config + DB + logs) — user opted into full removal.
var appData = Paths.AppDataRoot();
if (Directory.Exists(appData))
{
progress.Report($"Deleting {appData}...");
TryDeleteDir(appData);
}
progress.Report("Uninstall complete.");
return StepResult.Ok();
}
private static void TryDeleteFile(string path)
{
try { if (File.Exists(path)) File.Delete(path); } catch { /* best effort */ }
}
private static void TryDeleteDir(string path)
{
try { Directory.Delete(path, recursive: true); } catch { /* best effort */ }
}
}