fix(installer): unbreak the update path and cache the download
Changelog / changelog (push) Successful in 2s
Release / release (push) Successful in 40s

Every update failed at "Could not replace the existing files": the app
relaunches the installer via ShellExecute without a working directory, so
it inherited the app's CWD - which the Start Menu shortcut sets to
<InstallDir>\app. A process's current directory is locked by Windows, so
the installer blocked its own `app` -> `app.bak` rename. Retries and
reboots could not help.

- installer moves its CWD to %TEMP% at startup, and both relaunch sites
  in the UI pass an explicit WorkingDirectory
- cache the release zip in %TEMP%\ClaudeDo-download-cache and reuse it on
  a retry while its SHA-256 still matches, so a failed attempt no longer
  costs another full download; drop it after a successful install, delete
  a mismatching one, prune zips of other versions
- roll back a half-done stash: a leftover app.bak was deleted as a stale
  stash on the next attempt, and that copy was the only one left
- name the blocked path in the error message
This commit is contained in:
Mika Kuns
2026-08-04 17:09:10 +02:00
parent ab56644ddc
commit 63d8b5c28d
6 changed files with 224 additions and 35 deletions
@@ -496,7 +496,13 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
try
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(path) { UseShellExecute = true });
// WorkingDirectory must NOT stay empty: the child would inherit ours (<InstallDir>\app)
// and its locked current directory blocks the installer's own app\ rename.
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(path)
{
UseShellExecute = true,
WorkingDirectory = System.IO.Path.GetTempPath(),
});
Environment.Exit(0);
}
catch
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using ClaudeDo.Ui.Services;
using CommunityToolkit.Mvvm.Input;
@@ -37,7 +38,13 @@ public sealed partial class WorkerConnectionModalViewModel : ViewModelBase
if (path is null) return;
try
{
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
// See IslandsShellViewModel.UpdateNow: an inherited CWD inside the install dir
// makes the installer block its own app\ rename.
Process.Start(new ProcessStartInfo(path)
{
UseShellExecute = true,
WorkingDirectory = Path.GetTempPath(),
});
Environment.Exit(0);
}
catch { /* nothing useful to show */ }