【问题标题】:Waiting for NSIS uninstaller to finish in NSIS installer either fails or the uninstaller won't be deleted在 NSIS 安装程序中等待 NSIS 卸载程序完成要么失败,要么卸载程序不会被删除
【发布时间】:2014-08-27 01:37:12
【问题描述】:

使用 NSIS,我想在安装新版本之前从我的安装程序中调用以前安装的版本的卸载程序。这个proposed solution就是执行下面的命令:

ExecWait '"$INSTDIR\uninstall.exe" _?=$INSTDIR'

据我了解,需要_?=$INSTDIR 才能使ExecWait 真正等待。没有它,NSIS 会将卸载程序复制到临时目录,在那里启动它,然后在卸载程序完成之前返回。这个解决方案的问题是,卸载程序直接在 $INSTDIR 中执行。这导致我的卸载程序中的以下命令失败:

Delete "$INSTDIR\uninstall.exe"

据我了解,uninstall.exe没有被删除的原因是,当前正在执行的文件不能被删除。总结一下我的问题:

ExecWait '"$INSTDIR\uninstall.exe"'

不等待卸载程序完成并且

ExecWait '"$INSTDIR\uninstall.exe" _?=$INSTDIR'

不允许卸载程序自行删除。有谁知道,如何在等待卸载程序完成的同时让卸载程序在卸载过程中立即删除自己?

【问题讨论】:

  • ExecWait 总是等待子进程,在你的情况下,这个子进程很快就会完成......
  • 我读到 ExecWait 只等到卸载程序被复制到临时目录并在临时目录中启动。它绝对不会等待卸载程序完成。我使用一些消息框对此进行了测试。
  • ExecWait 是一个通用指令,它总是等待子进程,您执行的东西(卸载程序)将快速退出的事实不是 ExecWaits 错误。 ExecWait 是原生 CreateProcess 和 WaitForSingleObject 函数的薄包装......
  • 我想我们的理解是一样的。我的想法不是在这里责怪 ExecWait。我想提一下,使用 ExecWait 的给定解决方案并没有达到我的预期。

标签: installation nsis uninstallation


【解决方案1】:

_?= 参数告诉卸载程序它应该 将自身复制到%temp% 并执行该复制而不等待它完成。 _?=之后的路径用于在卸载程序中初始化$InstDir。

在您的安装程序中,您可以执行以下操作:

InitPluginsDir
;ReadRegStr $oldinstall ... ; Somehow detect old install
CreateDirectory "$pluginsdir\unold" ; Make sure plugins do not conflict with a old uninstaller 
CopyFiles /SILENT /FILESONLY "$oldinstall\uninst.exe" "$pluginsdir\unold"
ExecWait '"$pluginsdir\unold\uninst.exe" _?=$oldinstall'

【讨论】:

  • 感谢您的回答!我实际上希望有一个想法;)你的解决方案看起来很棒。我只花了半个小时就明白了 :) 你真的给了我一些新东西!给我一些时间尝试一下...
  • 好的,我将您的解决方案集成到我的安装程序中并对其进行了测试。完美运行!再次感谢!
猜你喜欢
  • 2011-06-08
  • 2013-02-10
  • 2012-01-26
  • 2014-09-27
  • 2015-02-06
  • 2014-09-13
  • 1970-01-01
  • 2013-02-20
  • 2016-06-30
相关资源
最近更新 更多