场景
正在通过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,卸载程序将主要变成Uninstall.exe,如果存在,则假设以前的安装存在于目标文件夹中,并省略了!insertmacro UNINSTALL.LOG_OPEN_INSTALL和相应的关闭调用。这是相当好的工作,但将收集所有文件一次在最初的安装。作为更新的一部分添加的文件,即当用户通过现有安装安装时,将不再在Uninstall.dat.Uninstall.dat。不可能,因为很明显,这个文件是在安装程序部分之前读取的,并且是在安装程序部分之后编写的,因此,一旦安装程序完成,我的convenience.nsisExec触发卸载。这是胡说八道,因为它将打开一个新的卸载窗口之上的安装程序窗口,并采取焦点,如预期。这在用户看来很糟糕,因为突然有两个安装窗口竞争他们的focus.AdvUninstLog,因为卸载是使用其宏实现的,而且这些宏仅对卸载部分有效。问题
!insertmacro UNINSTALL.LOG_OPEN_INSTALL?RMDir /r $path,但是这与没有/r的RMDir具有完全相同的效果,即文件夹正在被删除,但是只有一次是空的。怎么回事?自2004年以来,有一些线程描述了这些问题,下面是一些例子:
我有兴趣找到一个程序,以保持Uninstall.dat的最新,但防止荒谬的长调用造成的AdvUninstLog插件。我怎样才能做到这一点?
发布于 2020-01-13 20:07:18
我更喜欢另一个标题使用的方法( AdvUninstLog页面也提到了这一点):https://nsis.sourceforge.io/Uninstall_only_installed_files
与AdvUninstLog类似,卸载日志仅用于退出已安装的文件和注册表项,尽管此标头要求您使用包装文件、WriteRegStr等调用的宏。
我发现,允许取消的安装与此头一起回滚其更改是一种很好的方法:https://nsis.sourceforge.io/InstFiles_Cancel_-_Allowing_a_user_to_cancel_installation_during_InstFiles (但请注意,如果您需要回滚更新,它会更难一些,因为您需要首先备份现有安装)。
这个头具有AdvUninstLog的许多相同的优点,但是AdvUninstLog的好处是,即使您在文件调用中使用通配符,卸载也只会删除实际安装的文件,但是成本是您观察到的性能缓慢的潜在因素。在这两种情况下,您都需要弄清楚如何处理事后添加的文件。
Re:问题1和问题2,甚至AdvUninstLog页面也提到了这个缺点(尽管没有提到原因)。至于问题3,目前还不清楚,但在关闭Uninstall.dat之前,您可能正在尝试这样做。在紧急情况下,您可以始终使用"RMDir /r /REBOOTOK“,并允许Windows在重新启动后完成清理。
https://stackoverflow.com/questions/59663044
复制相似问题