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

如何在NSIS脚本中从注册表提取不含uninstall.exe的原安装路径?

解决NSIS脚本中从UninstallString提取不含uninstall.exe的安装目录问题

我需要在NSIS脚本中通过注册表识别已安装程序的目录,已定位到注册表项HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PaperTrlQBDConnector"下的UninstallString,其值格式为\xxx\xxxx\PaperTrlQBDConnector\uninstall.exe。目标是提取不含uninstall.exe的路径到变量中,但当前使用的PreDirCheck函数获取的路径仍包含该文件名,需要修正。

原函数代码如下:

Function PreDirCheck

         # discover if QBD Connector is already installed
         ClearErrors
         
         SetRegView 64

         ClearErrors
         ;ReadRegStr $previous_install_dir HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PaperTrlQBDConnector" "PreDir"
         ;${if} $previous_install_dir == 0
         ReadRegStr $previous_install_dir HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PaperTrlQBDConnector" "UninstallString"
         ;${Endif}
         
         
         IfErrors done
         ;sectionsetflags ${sec1} 0
         SetAutoClose false
         strcpy $INSTDIR $previous_install_dir
         MessageBox MB_ICONQUESTION|MB_YesNO|MB_DEFBUTTON2 "Detected previous version in Directory $previous_install_dir $\n Click Yes To update in the existing directory $\n Click No to completely remove PaperTrl SyncManager and install to a new location?" IDYes lbl_abort IDNo lbl_un

         lbl_abort:
         sectionsetflags ${sec2} 0
         Abort ;skip page
         

         lbl_un:
         !insertmacro UninstallExisting
         sectionsetflags ${sec2} 1

    done:
         SetAutoClose false
        ;!insertmacro MUI_PAGE_DIRECTORY
         sectionsetflags ${sec2} 1

FunctionEnd

解决方案

利用NSIS内置的字符串处理函数,先定位UninstallString中最后一个反斜杠的位置,再截取该位置之前的内容,即可得到不含uninstall.exe的目录路径。同时需处理路径可能被双引号包裹的情况。

修改后的PreDirCheck函数代码:

Function PreDirCheck

         # discover if QBD Connector is already installed
         ClearErrors
         
         SetRegView 64

         ClearErrors
         ;ReadRegStr $previous_install_dir HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PaperTrlQBDConnector" "PreDir"
         ;${if} $previous_install_dir == 0
         ReadRegStr $previous_install_dir HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PaperTrlQBDConnector" "UninstallString"
         ;${Endif}
         
         
         IfErrors done
         ; 处理UninstallString,提取不含uninstall.exe的目录
         ; 先移除可能存在的首尾双引号
         StrCpy $R0 $previous_install_dir 1
         ${If} $R0 == '"'
             StrLen $R1 $previous_install_dir
             IntOp $R1 $R1 - 1
             StrCpy $previous_install_dir $previous_install_dir 1 -1 $R1
         ${EndIf}
         ; 查找最后一个反斜杠的位置
         StrRFind $R0 $previous_install_dir "\"
         ${If} $R0 != -1 ; 找到反斜杠
             StrCpy $previous_install_dir $previous_install_dir 0 $R0 ; 截取到反斜杠位置
         ${EndIf}
         
         ;sectionsetflags ${sec1} 0
         SetAutoClose false
         strcpy $INSTDIR $previous_install_dir
         MessageBox MB_ICONQUESTION|MB_YesNO|MB_DEFBUTTON2 "Detected previous version in Directory $previous_install_dir $\n Click Yes To update in the existing directory $\n Click No to completely remove PaperTrl SyncManager and install to a new location?" IDYes lbl_abort IDNo lbl_un

         lbl_abort:
         sectionsetflags ${sec2} 0
         Abort ;skip page
         

         lbl_un:
         !insertmacro UninstallExisting
         sectionsetflags ${sec2} 1

    done:
         SetAutoClose false
        ;!insertmacro MUI_PAGE_DIRECTORY
         sectionsetflags ${sec2} 1

FunctionEnd

关键代码说明

  • 处理双引号:部分程序的UninstallString会用双引号包裹路径,通过判断首尾字符是否为",截取中间内容去除引号。
  • 定位最后一个反斜杠:使用StrRFind函数查找路径中最后一个\的索引,若找到则用StrCpy截取该索引之前的字符串,得到不含uninstall.exe的目录路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:35:19