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
- 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 钩子编译位置修正小节与本机探针取证
103 lines
5.8 KiB
NSIS
103 lines
5.8 KiB
NSIS
; 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
|