How to stop a running process during an MSI based

2019-02-24 05:37发布

I'm using Wise Package Studio 7.0 SP2 on Windows XP.

I've got an MSI Wrapped EXE installation that goes about happily installing some files and then running one of the files from the installation which we can refer to as app.exe.

So on the "Execute Deferred" tab of the MSI Editor, I had to add the lines:

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

This ensured that my app.exe would be run only on an installation and not during a modify/repair/removal. When app.exe runs, it conveniently adds itself to the system tray.

I'm looking for something that will do the reverse during a removal. I want to stop the app.exe process thus removing it from the system tray.

Currently my removal gets rid of all the files however the app.exe remains running and still shows up in the systems tray. I've looked at adding the conditional statement:

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

The conditional statement will let me do something only on a removal, however I'm not sure of the best approach to go about actually terminating the process. Is there an MSI command I can run that will let me do that? Should I write my own .exe that will do that?

4条回答
戒情不戒烟
2楼-- · 2019-02-24 06:03

6 months ago we were using VBScript actions to do the same thing, then right around the time that SP3 was released the objProcess.Terminate() function just refused to work on some machines. No matter what we did, it just froze. This happened on around 10% of our test machines so we were forced to find an alternative solution (who knows how many customers it might have frozen on!)

My first discovery was the inbuilt (since Windows 2000) command TASKKILL eg: TASKKILL /IM app.exe /F but as that seems to use similar means of killing a process as we used in VBScript, that method would also fail.

So now we're using the pskill.exe tool from sysinternals, you need to use a command line switch to supress the license agreement prompt but other than that, it's been the most foolproof way of killing a running EXE that I've found.

Of course the best solution would be to build your own EXE or DLL to do it should you happen to know a little C++ ;)

查看更多
家丑人穷心不美
3楼-- · 2019-02-24 06:16

Just terminating processes isn't sufficient, since that doesn't clean up the Windows Notification Area (however, Windows will clean up an icon with no matching process when the mouse next hovers over in). Yet one more reason why terminating apps abruptly is generally best reserved for debugging. Unfortunately, a more proper solution is also more involved. You could create a named event in the app and register a callback method to be called when it is set. The callback would close the app. Then you'd write a custom action that set the event and waited until process terminated.

If you need to support cancellation (e.g. the user is prompted that he has unsaved changes and decides not to cancel), you may use another named event to indicate that, so the custom action may wait for either the process to end or a cancellation event, whichever comes first.

查看更多
时光不老,我们不散
4楼-- · 2019-02-24 06:16

You can insert VBscript elements into the MSI as custom actions. Something like this should do the job:

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
查看更多
小情绪 Triste *
5楼-- · 2019-02-24 06:17

If your app.exe was created in house, you could add a command line that tells it to kill the one that's currently running. When given that command line, it would send that first instance of the program a message or something that tells it to quit and then hang around just waiting until that first instance of the program has actually terminated. The installer would then be able to run the program with the kill switch and know that the original instance of it is gone when the kill switched instance has returned.

查看更多
登录 后发表回答