NSIS检测并卸载已有版本,静默卸载隐藏MessageBox

Posted 一如年少模样

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NSIS检测并卸载已有版本,静默卸载隐藏MessageBox相关的知识,希望对你有一定的参考价值。

接触到NSIS制作安装包,检测并卸载已有版本,项目要把已有项目删除,百度了方法,遇到了不少坑,慢慢的,现在的版本应该可以使用了。希望可以帮到一些人。

废物不多说,先看下原本百度的代码:

Var UNINSTALL_PROG
Var OLD_VER
Var OLD_PATH


Function .onInit
  ClearErrors
  ReadRegStr $UNINSTALL_PROG $PRODUCT_UNINST_ROOT_KEY $PRODUCT_UNINST_KEY "UninstallString"
  IfErrors  done

  ReadRegStr $OLD_VER $PRODUCT_UNINST_ROOT_KEY $PRODUCT_UNINST_KEY "DisplayVersion"
  MessageBox MB_YESNOCANCEL|MB_ICONQUESTION \\
    "检测到本机已经安装了 $PRODUCT_NAME $OLD_VER。\\
    $\\n$\\n是否先卸载已安装的版本?" \\
      /SD IDYES \\
      IDYES uninstall \\
      IDNO done
  Abort

uninstall:
  StrCpy $OLD_PATH $UNINSTALL_PROG -10


  ExecWait '"$UNINSTALL_PROG" /S _?=$OLD_PATH' $0
  DetailPrint "uninst.exe returned $0"
  Delete "$UNINSTALL_PROG"
  RMDir $OLD_PATH


done:
FunctionEnd

分析下以上代码:

声明几个变量,在安装初始化回调方法中,清除错误标记,读取注册表

ReadRegStr 用户变量(输出) 根键 子键 项

上文读取卸载路径字符串并输出到用户变量$UNINSTALL_PROG,弹出MessageBox执行各操作,我看看下IDYES,执行卸载方法

 uninstall:
      StrCpy $OLD_PATH $UNINSTALL_PROG -10


      ExecWait '"$UNINSTALL_PROG" /S _?=$OLD_PATH' $0
      DetailPrint "uninst.exe returned $0"
      Delete "$UNINSTALL_PROG"
      RMDir $OLD_PATH

我们拿到的变量UNINSTALLPROG是带有uninst.exe的,-10 拿到所谓的安装路径,输出到变量$OLDPATH,然后执行ExecWait 执行uninst.exe

/S(区分大小写)表示静默卸载,

_?= 指定 $INSTDIR 这也会阻止卸载程序把它自己复制到临时文件夹再运行。这将可以使用 ExecWait 来运行卸载程序并等待它完成。这个参数必须是最后一个参数并且不能带任何引号即使路径带有空格。把&0作为返回代码

这地方或许会遇到一个问题,但我们执行uninst.exe的时候,我们是执行的卸载,我们执行卸载肯定会调用un.onInit un.onUninstSuccess回调函数,以及卸载过程中的用户函数,我当时就遇到MessageBox弹出的问题,严重影响使用,这个时候我们可以使用 /SD 来指定一个上面列出的返回值当在卸载或安装程序静默卸载或安装时作为返回值

举个例子:卸载初始化的时候,提示是否卸载,

MessageBox MB_YESNO "确定要移除 $(^Name) ?" /SD IDYES IDYES +2

格式为:

 MessageBox MB_XX text [/SD IDXX] [IDXX target1] [IDXX target2] ...

这样就可以完成检测并卸载的过程了,当卸载过程结束我们再执行安装过程。

以上是关于NSIS检测并卸载已有版本,静默卸载隐藏MessageBox的主要内容,如果未能解决你的问题,请参考以下文章

NSIS 的卸载程序运行速度非常快

NSIS 如何在卸载时检测软件是不是运行并提示用户

Android静默安装与静默卸载(系统应用)

根据安装程序的 NSIS 卸载程序权限

如何要求用户使用 NSIS 卸载以前的版本

NSIS目录