Reference· 04
App identity & upgrades
The easiest thing to get wrong in packaging and the hardest to notice — AppId decides whether a rebuild upgrades in place or installs a second copy.
How Inno decides “upgrade” versus “fresh install”
Inno recognises an application by its AppId, recorded at
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\<AppId>_is1:
- Same AppId → a new version of the same app: it upgrades in place, updates the version in the uninstall
entry, and defaults to the previous install directory (
UsePreviousAppDirdefaults toyes); - Different AppId → a different app: a fresh install, and both versions sit side by side in “Installed apps”.
So the AppId must stay identical across all builds of the same product.
Why the project id cannot be the AppId
The project id is a random UUID generated when you create a project. Using it as the AppId means:
- rebuilding the same project → same AppId → it does upgrade;
- switching to another project (even with the same executable) → different AppId → fresh install, two versions side by side.
Which is exactly the “I changed three lines, rebuilt, and now there are two programs” report.
What it does now
The AppId is derived from the executable’s product identity: ProductName + CompanyName +
OriginalFilename from the version resource (falling back to the filename), concatenated, hashed
deterministically and shaped like a UUIDv5.
- the same executable recompiled, repackaged, or packaged on another machine → same AppId;
- a changed
ProductNameorCompanyName→ a different AppId — which is correct, it is a different product; - the derived value is filled into “app identity” and can be edited by hand (to force a different identity, or to reconnect to an old AppId).
The derivation (commands.rs::detect_app_id) is pinned by unit tests: deterministic, different products
differ, valid UUID shape, case-only changes do not count as a new product, and fields cannot bleed into
each other.
Two easy-to-miss preconditions
PrivilegesRequiredmust not change between builds. It decides whether Inno writes the uninstall record under HKCU or HKLM; if the previous build was per-user and this one requires admin, the second build cannot find the first installation and installs fresh.- Portable mode (
packagingMode=portable) has no upgrades. It writesUninstallable=noandCreateUninstallRegKey=no, so Inno has nothing to look up and every run unpacks fresh. That is intentional.
The one-time migration
The AppId scheme changed in v0.1.1 (v0.1.0 used the project id). As a consequence:
An installer built with v0.1.0 and one built with v0.1.1 or later have different AppIds and will not upgrade each other — once. To reconnect, paste the old value into “app identity” by hand.
How to confirm your build is right
- Build twice (or bump the version and rebuild) and install both;
- Open Settings → Apps → Installed apps and confirm there is exactly one entry;
- Or look at the registry: under
HKCU\...\Uninstall\theDisplayVersionon that single_is1key changed and the key count did not.