Files
Genarrative/apps/ai-game-creator-shell/src-tauri/windows/installer-hooks.nsh
T
kdletters 30a190d183
Project CI / AI game creator shell Rust crates (push) Successful in 1m32s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m57s
Project CI / Backend tests (push) Successful in 4m6s
Project CI / Frontend tests (push) Successful in 2m11s
Project CI / Native shell tests (push) Successful in 6m11s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m0s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m19s
Project CI / AI game creator shell web tests (push) Failing after 1m48s
Project CI / Repository checks (push) Successful in 2m33s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
修复 AGC NSIS 安装钩子在模板常量与插件目录之前编译导致的出包失败
- installer-hooks.nsh 顶层收敛为 !define / Var / !macro:迁移逻辑改成 !macro AgcMigrateLegacyIdentity,由 !macro NSIS_HOOK_POSTINSTALL 在模板插入点(Section Install,addplugindir 之后)展开,避免 include 时 INSTALLMODE 未定义走错分支、nsis_tauri_utils 插件目录还没 add 导致 makensis 报 Plugin not found 中断
- 旧展示名改走运行期变量 $AgcLegacyIdentity(替换 Push/Pop + Function),去掉 section 上下文里不可用的 Return 提前返回,清理与补建语义保持不变
- 文件头补编译期位置纪律:模板在 installer.nsi 第 28 行 include 本文件,早于 !define INSTALLMODE / MAINBINARYNAME 与 !addplugindir,顶层只能放声明
- build-release.test.mjs 新增守卫用例:顶层不得出现 Function、插件调用、模板常量引用或裸可执行语句(对修复前形态命中 36 条,含第 68 行顶层插件调用)
- pitfalls 与 decision-log 记录该踩坑、根因、本机逐字复现与处理口径
- AGC 渠道安装身份隔离里程碑补 2026-09-29 钩子编译位置修正小节与本机探针取证
2026-09-29 18:00:03 +08:00

103 lines
5.8 KiB
NSIS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; AGC dev 渠道安装身份改名的迁移钩子(NSIS installer hooks,随 Windows 包体编译)。
;
; 背景:dev 渠道的展示名改过两次(Genarrative AI Game Creator → 陶泥儿 → 陶泥儿开发版),
; identifier 保持不变。Tauri 的 NSIS 模板在更新模式(/UPDATE)与 /NS 下**不创建快捷方式**,
; 只会把「同名」快捷方式的目标改写回主程序名(见 installer.nsi 的 CreateOrUpdate*Shortcut)。
; 展示名一改,旧快捷方式既不会被改写、也不会被新建,于是升级后:
; - 旧安装目录与旧快捷方式留在原地,桌面快捷方式继续拉起旧 exe;
; - 旧 exe 的更新器仍然指向同一份 latest.json,又一次把新版本装进新目录并自动启动。
; 用户看到的就是「更新后自动启动的是新版,但桌面快捷方式打开的还是旧的」这个循环。
;
; 因此安装结束时做两件事:
; 1. 旧身份(改名前的展示名)的快捷方式、安装目录与卸载项整体清理,旧 exe 不再能被拉起;
; 2. 被迁移过的机器按当前身份补建快捷方式:桌面图标只在用户原本就有旧图标时迁移,
; 不替用户新增;开始菜单图标始终补建,避免自更新后应用失去入口。
;
; 该文件只注入 dev 渠道(改名发生在 dev 渠道)的 Windows 包;其它渠道的展示名从未变过,
; 不能拿这份旧身份表去删它们的安装。
;
; ⚠️ 编译期位置(改本文件前必读):Tauri 2.11 的 NSIS 模板在 installer.nsi 第 28 行
; `!include` 本文件,位置早于 `!define INSTALLMODE` / `!define MAINBINARYNAME` 等模板常量,
; 也早于 `!addplugindir "${ADDITIONALPLUGINSPATH}"`(nsis_tauri_utils 插件目录)。所以顶层只能放
; !define / Var / !macro 这类声明:
; - 顶层引用 `${MAINBINARYNAME}`、`${PRODUCTNAME}` 会命中未定义常量(makensis warning 6000),
; 字符串被静默替换成空文本;
; - 顶层写 `!if "${INSTALLMODE}" == "currentUser"` 会走错分支(此时 INSTALLMODE 还是空值);
; - 顶层调用 nsis_tauri_utils::* 会直接 `Plugin not found`,打包在 makensis 这一步整条中断。
; 可执行逻辑一律写进 !macro:宏体在模板的 `!insertmacro NSIS_HOOK_*` 处展开(Section Install,
; 位于 addplugindir 之后),那时模板常量与插件都已就绪。
; 旧展示名表:以后再改展示名,必须在这里追加旧名,否则升级后旧快捷方式会继续指向旧安装。
!define AGC_LEGACY_IDENTITY_1 "陶泥儿"
!define AGC_LEGACY_IDENTITY_2 "Genarrative AI Game Creator"
Var AgcLegacyIdentity
Var AgcLegacyInstallDir
Var AgcMigratedLegacyDesktopShortcut
; 清理一个旧身份。调用方先把旧展示名写进 $AgcLegacyIdentity,再 !insertmacro 本宏;宏不返回错误。
; 只在「旧展示名目录下确实存在我们的主程序」时才动手,避免误删同名目录;
; 当前安装目录 $INSTDIR 永不进入删除路径。
!macro AgcMigrateLegacyIdentity
StrCpy $AgcLegacyInstallDir ""
${If} ${FileExists} "$LOCALAPPDATA\$AgcLegacyIdentity\${MAINBINARYNAME}.exe"
StrCpy $AgcLegacyInstallDir "$LOCALAPPDATA\$AgcLegacyIdentity"
${ElseIf} ${FileExists} "$PROGRAMFILES64\$AgcLegacyIdentity\${MAINBINARYNAME}.exe"
StrCpy $AgcLegacyInstallDir "$PROGRAMFILES64\$AgcLegacyIdentity"
${EndIf}
${If} $AgcLegacyInstallDir != ""
${AndIf} $AgcLegacyInstallDir != $INSTDIR
; 桌面图标:只有目标正好指向旧目录的主程序时才删,避免误删同名的用户快捷方式。
!insertmacro IsShortcutTarget "$DESKTOP\$AgcLegacyIdentity.lnk" "$AgcLegacyInstallDir\${MAINBINARYNAME}.exe"
Pop $0
${If} $0 = 1
StrCpy $AgcMigratedLegacyDesktopShortcut 1
!insertmacro UnpinShortcut "$DESKTOP\$AgcLegacyIdentity.lnk"
Delete "$DESKTOP\$AgcLegacyIdentity.lnk"
${EndIf}
; 开始菜单图标:必须先删掉,否则它会在当前身份图标补建后继续指向旧 exe。
!insertmacro IsShortcutTarget "$SMPROGRAMS\$AgcLegacyIdentity.lnk" "$AgcLegacyInstallDir\${MAINBINARYNAME}.exe"
Pop $0
${If} $0 = 1
!insertmacro UnpinShortcut "$SMPROGRAMS\$AgcLegacyIdentity.lnk"
Delete "$SMPROGRAMS\$AgcLegacyIdentity.lnk"
${EndIf}
; 旧安装目录与卸载项整体清理:旧 exe 留着就会继续把新版本装进新目录。
; 先结束残留的旧实例(同名主程序):更新路径下调用方通常已退出,这里兜住手动启动的情况。
!if "${INSTALLMODE}" == "currentUser"
nsis_tauri_utils::KillProcessCurrentUser "${MAINBINARYNAME}.exe"
Pop $0
!else
nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
Pop $0
!endif
RMDir /r "$AgcLegacyInstallDir"
; 卸载项按展示名登记,旧名与当前名不同,必须按旧名清掉,否则「应用和功能」里会留下孤儿条目。
DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AgcLegacyIdentity"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AgcLegacyIdentity"
DeleteRegKey HKCU "Software\${MANUFACTURER}\$AgcLegacyIdentity"
${EndIf}
!macroend
!macro NSIS_HOOK_POSTINSTALL
StrCpy $AgcLegacyIdentity "${AGC_LEGACY_IDENTITY_1}"
!insertmacro AgcMigrateLegacyIdentity
StrCpy $AgcLegacyIdentity "${AGC_LEGACY_IDENTITY_2}"
!insertmacro AgcMigrateLegacyIdentity
; 迁移过的机器补建当前身份的快捷方式(更新模式下模板不会创建)。
StrCpy $R0 "$INSTDIR\${MAINBINARYNAME}.exe"
${IfNot} ${FileExists} "$SMPROGRAMS\${PRODUCTNAME}.lnk"
CreateShortCut "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$R0"
!insertmacro SetLnkAppUserModelId "$SMPROGRAMS\${PRODUCTNAME}.lnk"
${EndIf}
${If} $AgcMigratedLegacyDesktopShortcut = 1
CreateShortCut "$DESKTOP\${PRODUCTNAME}.lnk" "$R0"
!insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk"
${EndIf}
!macroend