4

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

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

因此,在 MSI 编辑器的“执行延迟”选项卡上,我必须添加以下行:

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

4 回答 4

2

6 个月前,我们使用 VBScript 动作来做同样的事情,然后就在 SP3 发布的时候,objProcess.Terminate() 函数拒绝在某些机器上工作。不管我们怎么做,它只是冻结了。这发生在我们大约 10% 的测试机器上,因此我们被迫寻找替代解决方案(谁知道它可能冻结了多少客户!)

我的第一个发现是内置的(从 Windows 2000 开始)命令 TASKKILL,例如:TASKKILL /IM app.exe /F但由于这似乎使用了与我们在 VBScript 中使用的类似的终止进程的方法,因此该方法也会失败。

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

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

于 2008-10-31T07:09:49.037 回答
1

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

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

于 2009-09-22T20:53:37.817 回答
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
于 2008-10-31T04:55:53.690 回答
0

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

于 2011-01-07T22:12:43.303 回答