Files
craft-libs/crates
JeremyandClaude Opus 5.5 df399edff8 craft-update: a Windows MSI copy updates itself in its own context, wherever it is installed (#419)
* craft-update: a Windows MSI copy updates itself in its own context, wherever it is installed

Self-update only recognised an MSI copy by the launcher's per-user folder (the HKCU InstallDir
key, or %LOCALAPPDATA%\Programs\<App>). Every app installed for everyone, in
Program Files\ArtCraft\<App> or the older Program Files\<App>, was treated as a loose folder and
updated by unpacking the portable zip over Program Files without permission.

- msi_context moves here from the launcher (craft-launcher crates/native/src/msi_context.rs at
  b827fed, unchanged apart from visibility, MsiScope and scope_arguments). Windows Installer's
  own registration decides a copy's context, for the launcher and the apps alike, so the
  launcher can drop its copy and both routes follow one rule.
- New msi_copy module: a copy is an MSI copy when an App Paths entry names its exe (a registry
  read, cheap enough for status checks). Its update asks Windows Installer for the context; the
  App Paths hive is only the fallback when that lookup cannot run.
- The update stops, before the app exits, when the copy is registered in both hives, the lookup
  is unclear, or Windows lists the app more than once.
- After the update the helper starts the exe the registrations name now, since the package may
  have moved an exact old default folder.
- A failed self-update now names the Windows Installer log, as the launcher's installs do.
- The launcher's own per-user package is recognised and updated exactly as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* craft-update: a copy only takes the Windows Installer context of its own hive

Review follow-up (CodeRabbit on #419). The product code for the context lookup came from the
app's only uninstall record, which was not proven to own the running exe. A package writes App
Paths under HKMU, always the hive of its own context, so a registration whose Windows Installer
context differs from the hive that named this exe belongs to another copy. The update now stops
then, instead of taking the other copy's context.

Also documents the remaining helpers the diff touches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* craft-update: an app in the old per-user folder is judged by its registration first

Review follow-up (CodeRabbit on #419). The folder rule for the launcher's per-user package also
matched an app installed in %LOCALAPPDATA%\Programs\<App>, and it ran before the App Paths
check, so such a copy skipped the product-count, conflict and context checks. Now an app is
judged by its registration first; the folder rule only covers an app copy no registration names.

The launcher in its own folder still keeps its old path whatever is registered: on a real PC it
has an App Paths entry and a stale second uninstall record, and registration-first would have
stopped its self-update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* craft-update: when the Windows Installer lookup cannot run, the uninstall records decide

Review follow-up (CodeRabbit on #419). The fallback trusted the App Paths hive, so a stale entry
or a product registered in both scopes could run the update in the wrong context. The fallback
now follows the launcher's rule: the context every uninstall record of the product agrees on
(msi_context::single_scope over HKLM in both views and HKCU). Missing or mixed records stop the
update, and an agreed context that differs from the App Paths hive still stops it as another
copy's registration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:26:20 -04:00
..
…