【发布时间】:2020-04-27 00:05:32
【问题描述】:
场景
正在通过 NSIS 安装应用程序。根据 NSIS 的要求,还提供了带有 Uninstaller.dat 的卸载程序。
希望收集在卸载过程中要删除的所有文件
!insertmacro UNINSTALL.LOG_OPEN_INSTALL!insertmacro UNINSTALL.LOG_CLOSE_INSTALL
它们都由AdvUninstLog 插件提供。然而这显然是不可能的。如果机器上已经存在卸载并且插件处于活动状态,则安装过程开始花费荒谬的时间,即 5-10 分钟。这是因为插件的${Locate} "${TargetDir}" "/L=FD" "${UnLog_Install_Func_CallBack}" 调用开始无休止地在安装目录中搜索文件。我不清楚为什么会发生这种行为。我的怀疑是,Uninstall.dat 包含不再存在且已被用户删除的文件,导致长时间搜索该文件。不过,我不确定。
尽管如此,事实上,这些调用会导致我们以及客户端计算机上的等待时间过长。
尝试处理此问题
- 省略
!insertmacro UNINSTALL.LOG_OPEN_INSTALL和相应的结束通话。这将导致Uninstall.dat为空,因此卸载程序几乎无用。 - 检查
Uninstall.exe是否存在,如果存在则假定目标文件夹中存在先前的安装并省略!insertmacro UNINSTALL.LOG_OPEN_INSTALL和相应的结束调用。这工作得很好,但只会在初始安装时收集所有文件。作为更新的一部分添加的文件,即当用户在现有安装上安装时,将不再在Uninstall.dat中识别。 - 在安装过程中尝试编辑
Uninstall.dat。不可能,因为显然这个文件是在安装程序部分之前读取并在安装程序部分之后写入的,所以一旦安装程序完成,我写入的任何内容都会被擦除,为了我的方便。 - 尝试在安装前触发卸载,使用
nsisExec。这是无稽之谈,因为它将在安装程序窗口上方打开一个新的卸载程序窗口并获得焦点,正如预期的那样。这对用户来说看起来很糟糕,因为突然有两个安装窗口在争夺它们的焦点。 - 如果检测到之前的安装,可能会在实际安装之前尝试调用卸载。但是,这需要我重写
AdvUninstLog,因为卸载是使用它的宏实现的,并且这些宏仅对卸载部分有效。
问题
- 为什么一开始就需要永远使用
!insertmacro UNINSTALL.LOG_OPEN_INSTALL? - 处理此问题的适当方法是什么?
- 我尝试使用
RMDir /r $path,但这与没有/r的RMDir具有完全相同的效果,即文件夹正在被删除,但只有一次为空。那里发生了什么?
自 2004 年以来就有描述这些问题的线程,以下是一些示例:
- http://forums.winamp.com/showthread.php?t=302976
- https://gitlab.com/inkscape/inkscape/issues/300
- https://nsis-dev.github.io/NSIS-Forums/html/t-356786.html
我有兴趣找到一个程序来保持Uninstall.dat 最新,同时防止由AdvUninstLog 插件引起的荒谬的长时间调用。我怎样才能做到这一点?
【问题讨论】:
-
您可以使用 ...\uninst.exe /S _?=$OldInstDir 静默运行卸载程序
-
我要试试。我当前的解决方案类似于我发布的线程之一,ie 我在编译时执行一个脚本,该脚本收集要由卸载程序处理的所有文件,然后生成一个包含宏的
.nsh和由卸载过程使用。
标签: installation nsis uninstallation