如何在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
相关产品推荐
相关产品推荐

