【问题标题】:NSIS: How do I uninstall previous version before install new version if programm name is changed?NSIS:如何在安装新版本的程序名称更改之前卸载以前的版本?
【发布时间】:2019-02-13 16:12:32
【问题描述】:

在写入注册表的我的程序名称中,有一个版本号(例如,它看起来像这样:“我的程序 3.1”)。安装较新版本3.2或3.3(等)时需要卸载旧安装,但不知道如何让安装程序通过版本号在注册表中找到以前的安装。是的,我学习了这个链接的示例:http://nsis.sourceforge.net/Auto-uninstall_old_before_installing_new 但是在这个示例中,注册表搜索是通过程序名称执行的。在我的例子中,程序的名称发生了变化,因为版本号已经改变,安装程序在安装新版本之前无法在注册表中找到这个条目来卸载旧版本。请告诉我,我该怎么做。

这是我的示例代码:

;Define main variables:
!define PRODUCT_NAME "My programm"
!define PRODUCT_VERSION "3.9"
!define PRODUCT_FULLNAME "${PRODUCT_NAME} ${PRODUCT_VERSION}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_FULLNAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_UNINSTALL_EXE "uninstall.exe"

;Registry is added by this:
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" '"$INSTDIR\${PRODUCT_UNINSTALL_EXE}" _?=$INSTDIR'

;Read the registry key value for uninstall previous installation:
ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString"
StrCmp $R0 "" done

但此命令在注册表中找不到条目,​​因为程序名称 ${PRODUCT_FULLNAME} 已经具有不同的版本号。 请告诉我如何使注册表中的条目仅查找“我的程序”程序的名称而不考虑版本号?

重要补充!

在上面的消息中,我忘记澄清一件事:我的安装程序是为安装在多个 3ds Max 版本中的插件而制作的。因此,注册表中的条目如下所示:一个版本的“我的程序 3.1 for 3dsMax 2014”,另一个版本的“我的程序 3.1 for 3dsMax 2018”。安装新版本的程序后,条目应如下所示:“我的程序 3.2 for 3dsMax 2014”和“我的程序 3.2 for 3dsMax 2018”。也就是说,只有我的程序的版本号应该更改,其他所有内容(“我的程序...”和“... for 3dsMax(3ds Max 版本)”应该保持不变。 感谢您的理解,并提前感谢您的帮助!

【问题讨论】:

  • UninstallString 通常不需要 _?= 参数。

标签: installation nsis uninstallation


【解决方案1】:

使用EnumRegKey 枚举卸载键:

Section
StrLen $3 "${PRODUCT_NAME}"
StrCpy $0 0
loop:
EnumRegKey $1 ${PRODUCT_UNINST_ROOT_KEY} "Software\Microsoft\Windows\CurrentVersion\Uninstall" $0
    StrCmp $1 "" done
    IntOp $0 $0 + 1
    StrCpy $2 $1 $3 ; Get ${PRODUCT_NAME} prefix
    StrCmp $2 "${PRODUCT_NAME}" 0 loop
    ReadRegStr $2 ${PRODUCT_UNINST_ROOT_KEY} "Software\Microsoft\Windows\CurrentVersion\Uninstall\$1" UninstallString
    StrCmp $2 "" loop
    ExecWait $2 ; (This assumes you stored the old versions with the _?= parameter)
    Goto loop
done:
SectionEnd

【讨论】:

  • 感谢您的回复!但是我忘了澄清一点,上面的附加信息是什么。
  • StrCpy $2 $1 $3 行可以更改,如果名称的开头始终相同并且与“${PRODUCT_NAME}”相同,则 $3 可以只是一个数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
相关资源
最近更新 更多