如何在基于MSI的卸载期间停止正在运行的进程?

时间:2008-10-30 18:19:32

标签: installer windows-installer wise altiris

我在Windows XP上使用Wise Package Studio 7.0 SP2。

我有一个MSI Wrapped EXE安装,可以快乐地安装一些文件,然后运行安装中的一个文件,我们可以称之为app.exe。

所以在MSI编辑器的“Execute Deferred”选项卡上,我不得不添加以下行:

If Not Installed then
  Execute Installed Program app.exe (Action)
End

这确保了我的app.exe在安装时只运行 ,而不是在修改/修复/删除期间运行。当app.exe运行时,它可以方便地将自己添加到系统托盘中。

我正在寻找能够在移除过程中执行相反操作的内容。我想停止app.exe进程,从而将其从系统托盘中删除。

目前我的删除功能已删除所有文件,但app.exe仍在运行,并仍显示在系统托盘中。我看过添加条件语句:

If REMOVE~="ALL" then
  *remove the app from the systray!*
End

条件语句只允许我在删除时执行某些操作,但是我不确定实际终止该过程的最佳方法。是否有可以运行的MSI命令让我这样做?我应该编写自己的.exe吗?

4 个答案:

答案 0 :(得分:2)

6个月前我们使用VBScript操作做同样的事情,然后就在SP3发布的时候,objProcess.Terminate()函数只是拒绝在某些机器上运行。无论我们做了什么,它都冻结了。这种情况发生在我们大约10%的测试机器上,所以我们不得不寻找替代解决方案(谁知道它可能冻结了多少客户!)

我的第一个发现是内置的(自Windows 2000以来)命令TASKKILL 例如:TASKKILL /IM app.exe /F但由于这似乎使用类似的方法来杀死我们在VBScript中使用的进程,该方法也会失败。

所以现在我们正在使用sysinternals中的pskill.exe工具,您需要使用命令行开关来抑制许可协议提示,但除此之外,它是杀死正在运行的EXE的最简单方法我找到了。

当然,最好的解决方案是构建自己的EXE或DLL来实现它,如果你碰巧知道一点C ++;)

答案 1 :(得分:1)

仅仅终止进程是不够的,因为这不会清理Windows通知区域(但是,当鼠标下一次悬停时,Windows将清除没有匹配进程的图标)。然而,突然终止应用程序的另一个原因通常最好保留用于调试。不幸的是,更合适的解决方案也涉及更多。您可以在应用程序中创建一个命名事件,并注册一个在设置时调用的回调方法。回调将关闭应用程序。然后,您将编写一个自定义操作来设置事件,并等待进程终止。

如果您需要支持取消(例如,提示用户他有未保存的更改并决定不取消),您可以使用另一个命名事件来指示,因此自定义操作可能会等待进程结束或取消活动,以先到者为准。

答案 2 :(得分:0)

您可以将VBscript元素作为自定义操作插入MSI。这样的事情应该可以胜任:

strMachine = "localhost"
strAppName = "notepad.exe"

Set objProcesses = GetObject("winmgmts://" & strMachine).ExecQuery("SELECT * FROM Win32_Process WHERE Caption LIKE '" & strAppName & "'")

For Each objProcess In objProcesses
    intRetVal = objProcess.Terminate(0)
Next

答案 3 :(得分:0)

如果你的app.exe是在内部创建的,你可以添加一个命令行来告诉它杀死当前正在运行的那个。当给出该命令行时,它会向该程序的第一个实例发送一条消息或某些东西,告诉它退出然后等待,直到该程序的第一个实例实际终止为止。然后安装程序可以使用kill开关运行程序,并且知道当kill kill实例返回时它的原始实例已经消失。