You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NSIS中检测软件安装路径并实现同路径静默更新

解决NSIS自动安装到旧版本路径的问题

你的问题核心在于当前脚本的.onInit函数硬覆盖了$INSTDIR的值,同时需要确保旧版本的安装路径被正确写入注册表,让新版本能读取到。下面是具体的修复方案:

关键问题分析

  1. 你虽然定义了InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "",但在.onInit中检测到64位系统时,直接用StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"覆盖了从注册表读取的旧路径,这就导致新版本不管旧路径在哪,都强制装到Program Files 64位目录。
  2. 需要确保旧版本安装时,把实际安装路径写入注册表,这样新版本才能正确读取。

修复步骤及修改后的代码

1. 修正.onInit函数,保留注册表读取的旧路径

把原来的.onInit函数替换成以下内容,这样64位系统下会先尝试读取旧路径,而不是直接硬编码:

Function .onInit
    !insertmacro MULTIUSER_INIT

    ; 先尝试读取旧版本的安装路径(处理64位/32位注册表视图)
    ${If} ${RunningX64}
        SetRegView 64
        ReadRegStr $R0 HKLM "${PRODUCT_DIR_REGKEY}" ""
        ${If} $R0 == ""
            SetRegView 32
            ReadRegStr $R0 HKLM "${PRODUCT_DIR_REGKEY}" ""
        ${EndIf}
    ${Else}
        ReadRegStr $R0 HKLM "${PRODUCT_DIR_REGKEY}" ""
    ${EndIf}

    ; 如果读取到旧路径,就用它作为$INSTDIR
    ${If} $R0 != ""
        StrCpy $INSTDIR $R0
    ${Else}
        ; 没有旧路径时,才用默认路径
        ${If} ${RunningX64}
            StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"
        ${Else}
            MessageBox MB_OK "${PRODUCT_NAME} needs 64bit Windows!"
            Abort
        ${EndIf}
    ${EndIf}

    ; 检查是否有旧版本需要卸载
    ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
    StrCmp $R0 "" done uninst
uninst:
    ClearErrors
    Exec '$R0'
done:
FunctionEnd

2. 确保安装时写入路径到注册表

在Section "MainSection"的末尾添加写入注册表的代码,把当前安装路径存入指定键,供后续版本读取:

Section "MainSection" SEC01
    Call EnsureNotRunning
    ; ... 你的原有删除、复制文件代码 ...

    ; 写入安装路径到注册表,供后续版本读取
    ${If} ${RunningX64}
        SetRegView 64
    ${EndIf}
    WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\MyApp.exe"
    WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
SectionEnd

3. 保留默认路径的兜底逻辑

保持InstallDir作为无旧版本时的默认路径,同时确保InstallDirRegKey的优先级更高:

; 无旧版本时使用默认路径,会被注册表读取的旧路径覆盖
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""

额外说明

  • 如果你的旧版本没有写入${PRODUCT_DIR_REGKEY},第一个新版本还是会用默认路径,但之后的版本就能自动继承安装路径了。
  • 确认${PRODUCT_DIR_REGKEY}的路径和旧版本注册的App Paths项一致,避免读取失败。

内容的提问来源于stack exchange,提问作者Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:25:50