fix(installer): stamp Hermes icon onto Hermes.exe via rcedit (no winCodeSign)

The unpacked Hermes.exe showed the stock Electron icon + name in the
taskbar because build.win.signAndEditExecutable=false disables BOTH
electron-builder's signing AND its rcedit metadata/icon stamping. That
flag is load-bearing: enabling it re-triggers signtool -> winCodeSign,
whose macOS symlinks crash 7-Zip on non-admin Windows (unfixable dead end).

Decouple identity-stamping from signing entirely: after npm run pack,
run rcedit ourselves on the produced exe.
- Add rcedit as a direct devDependency of apps/desktop (the transitive
  electron-winstaller copy is fragile).
- apps/desktop/scripts/set-exe-identity.cjs: Node helper that calls
  rcedit's named export to set icon + ProductName/FileDescription/
  CompanyName. Node builds argv natively — avoids the PowerShell->exe
  ->JSON double-escaping that broke the app-builder rcedit path.
- install.ps1 Set-DesktopExeIdentity invokes the script after the build,
  before shortcuts. Best-effort: failure keeps the stock icon, never
  fails the install. rcedit is a pure PE editor — no signtool, no
  winCodeSign, no symlinks.

Verified locally: stamping a copy of the built Hermes.exe embeds the
32x32 icon and sets ProductName=Hermes.

Also fix update-path success-screen flash: in update mode the installer
hands off + exits in ~600ms, so don't route to the 'launch Hermes'
success view (it flashed before the window closed).
This commit is contained in:
emozilla 2026-05-29 00:50:14 -04:00
parent aeebe1afa7
commit 25488de4ba
5 changed files with 252 additions and 8 deletions

View file

@ -2014,13 +2014,13 @@ function Install-Desktop {
# launchable binary the Tauri installer can spawn.
#
# CSC_IDENTITY_AUTO_DISCOVERY=false tells electron-builder we are
# NOT signing the output. This short-circuits the winCodeSign fetch +
# extraction entirely (which fails on non-admin Windows due to a
# macOS-symlink extraction crash electron-builder hasn't fixed in
# years). We never had a signing cert to use, so the apparatus was
# dead weight that broke fresh installs. The produced Hermes.exe
# is functionally identical — just unsigned, same as it would be
# if signing had been attempted but no cert was configured.
# NOT signing the output. Combined with signAndEditExecutable=false in
# apps/desktop/package.json's build.win block, electron-builder never
# invokes signtool and therefore never fetches/extracts winCodeSign
# (whose macOS symlinks crash 7-Zip on non-admin Windows — a dead end we
# are NOT trying to work around). The Hermes icon + product name are
# stamped onto Hermes.exe by our own rcedit step (Set-DesktopExeIdentity)
# AFTER this build, completely decoupled from electron-builder signing.
#
# WIN_CSC_LINK and WIN_CSC_KEY_PASSWORD explicitly cleared as
# belt-and-suspenders: if the user's environment has them set
@ -2086,6 +2086,13 @@ function Install-Desktop {
throw "Desktop build completed but no Hermes.exe was found under $desktopDir\release\*-unpacked\"
}
# 3b. Stamp the Hermes icon + identity onto Hermes.exe ourselves.
# electron-builder's own rcedit step is disabled (signAndEditExecutable
# =false) because enabling it drags in signtool -> winCodeSign -> the
# unfixable symlink crash. So we run rcedit directly on the produced
# exe — no signing, no winCodeSign, just PE resource editing.
Set-DesktopExeIdentity -TargetExe $desktopExe -DesktopDir $desktopDir
# 4. Create Start Menu + Desktop shortcuts pointing DIRECTLY at the packed
# Hermes.exe. We deliberately do NOT point them at `hermes desktop`: that
# command rebuilds (npm install + electron-builder) on every launch,
@ -2095,6 +2102,57 @@ function Install-Desktop {
New-DesktopShortcuts -TargetExe $desktopExe
}
function Set-DesktopExeIdentity {
# Stamp the Hermes icon + version metadata into Hermes.exe via rcedit,
# delegated to apps/desktop/scripts/set-exe-identity.cjs (which uses the
# `rcedit` npm package — a direct devDependency, so always present).
#
# Why a Node script instead of calling rcedit from PowerShell: passing
# arguments through PowerShell -> exe -> JSON parsers double-escapes
# Windows backslashes and breaks app-builder's --args JSON. Letting Node
# build the rcedit argv natively sidesteps all shell-quoting hazards.
#
# This replaces electron-builder's built-in signAndEditExecutable step
# (kept false, because enabling it re-triggers signtool -> winCodeSign ->
# the macOS-symlink 7-Zip crash on non-admin Windows). rcedit is a pure PE
# resource editor — no signing, no certs, no winCodeSign, no symlinks.
#
# Best-effort: a stamping failure must not fail an otherwise-good install
# (worst case is the stock Electron icon, not a broken app).
param(
[Parameter(Mandatory = $true)][string]$TargetExe,
[Parameter(Mandatory = $true)][string]$DesktopDir
)
$nodeExe = Get-Command node -ErrorAction SilentlyContinue
if (-not $nodeExe) {
Write-Warn "node not on PATH; cannot stamp Hermes.exe identity (it will keep the stock Electron icon)"
return
}
$script = Join-Path $DesktopDir "scripts\set-exe-identity.cjs"
if (-not (Test-Path $script)) {
Write-Warn "set-exe-identity.cjs not found at $script; skipping exe identity stamp"
return
}
$prevEAP = $ErrorActionPreference
$ErrorActionPreference = "Continue"
# Run from $DesktopDir so the script's `require('rcedit')` resolves against
# the desktop workspace's node_modules.
Push-Location $DesktopDir
& $nodeExe.Source $script $TargetExe 2>&1 | ForEach-Object { "$_" }
$code = $LASTEXITCODE
Pop-Location
$ErrorActionPreference = $prevEAP
if ($code -eq 0) {
Write-Success "Stamped Hermes icon + identity onto $TargetExe"
} else {
Write-Warn "Exe identity stamp failed (exit $code); Hermes.exe keeps the stock Electron icon"
}
}
function New-DesktopShortcuts {
param([Parameter(Mandatory = $true)][string]$TargetExe)