处理 NSIS Uninstall.dat 和 AdvUninstLog 插件
Handling NSIS Uninstall.dat and the AdvUninstLog plugin
场景
正在通过 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
。这是无稽之谈,因为它会在安装程序 window 上方打开一个新的卸载程序 window 并获得焦点,正如预期的那样。这对用户来说简直太糟糕了,因为突然有两个安装 windows 争夺他们的焦点。
- 如果检测到先前的安装,可能会尝试在实际安装之前调用卸载。然而,这需要我重写
AdvUninstLog
,因为卸载是使用其宏实现的,并且这些仅对卸载部分有效。
问题
- 为什么一开始使用
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
会花很长时间?
- 处理这个问题的合适方法是什么?
- 我尝试使用
RMDir /r $path
,但这与 RMDir
没有 /r
的效果完全相同, 即 文件夹正在已删除,但只有一次为空。那里发生了什么?
自 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
插件引起的荒谬的长调用。我怎样才能做到这一点?
我更喜欢另一个 header 使用的方法(并且 AdvUninstLog 页面也提到了这个作为替代方法):
https://nsis.sourceforge.io/Uninstall_only_installed_files
与 AdvUninstLog 一样,卸载日志仅用于回退已安装的文件和注册表项,尽管这 header 要求您使用包装 File、WriteRegStr 等调用的宏。
我发现这是一个很好的方法,可以让取消的安装回滚它的更改连同 header:
https://nsis.sourceforge.io/InstFiles_Cancel_-_Allowing_a_user_to_cancel_installation_during_InstFiles
(但请注意,如果您需要能够回滚更新,这会有点困难,因为您需要先备份现有安装)。
此 header 与 AdvUninstLog 有很多相同的好处,但 AdvUninstLog 优于此的好处是,即使您在文件调用中使用通配符,您的卸载也只会删除文件实际安装的,但成本是您观察到的性能缓慢的可能性。在这两种情况下,您都需要弄清楚如何处理事后添加的文件。
回复:问题 #1 和 #2,甚至 AdvUninstLog 页面也提到了这个缺点(虽然没有说明原因)。至于问题 #3,目前还不清楚,但也许您在关闭 Uninstall.dat 之前尝试这样做。在紧要关头,您始终可以使用 "RMDir /r /REBOOTOK" 并允许 Windows 在重新启动后完成清理。
场景
正在通过 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
。这是无稽之谈,因为它会在安装程序 window 上方打开一个新的卸载程序 window 并获得焦点,正如预期的那样。这对用户来说简直太糟糕了,因为突然有两个安装 windows 争夺他们的焦点。 - 如果检测到先前的安装,可能会尝试在实际安装之前调用卸载。然而,这需要我重写
AdvUninstLog
,因为卸载是使用其宏实现的,并且这些仅对卸载部分有效。
问题
- 为什么一开始使用
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
会花很长时间? - 处理这个问题的合适方法是什么?
- 我尝试使用
RMDir /r $path
,但这与RMDir
没有/r
的效果完全相同, 即 文件夹正在已删除,但只有一次为空。那里发生了什么?
自 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
插件引起的荒谬的长调用。我怎样才能做到这一点?
我更喜欢另一个 header 使用的方法(并且 AdvUninstLog 页面也提到了这个作为替代方法): https://nsis.sourceforge.io/Uninstall_only_installed_files
与 AdvUninstLog 一样,卸载日志仅用于回退已安装的文件和注册表项,尽管这 header 要求您使用包装 File、WriteRegStr 等调用的宏。
我发现这是一个很好的方法,可以让取消的安装回滚它的更改连同 header: https://nsis.sourceforge.io/InstFiles_Cancel_-_Allowing_a_user_to_cancel_installation_during_InstFiles (但请注意,如果您需要能够回滚更新,这会有点困难,因为您需要先备份现有安装)。
此 header 与 AdvUninstLog 有很多相同的好处,但 AdvUninstLog 优于此的好处是,即使您在文件调用中使用通配符,您的卸载也只会删除文件实际安装的,但成本是您观察到的性能缓慢的可能性。在这两种情况下,您都需要弄清楚如何处理事后添加的文件。
回复:问题 #1 和 #2,甚至 AdvUninstLog 页面也提到了这个缺点(虽然没有说明原因)。至于问题 #3,目前还不清楚,但也许您在关闭 Uninstall.dat 之前尝试这样做。在紧要关头,您始终可以使用 "RMDir /r /REBOOTOK" 并允许 Windows 在重新启动后完成清理。