Как остановить работающий процесс во время деинсталляции на основе MSI? - PullRequest
4 голосов
/ 30 октября 2008

Я использую Wise Package Studio 7.0 SP2 в Windows XP.

У меня установлена ​​программа 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 ]

2 голосов
/ 31 октября 2008

6 месяцев назад мы использовали действия VBScript, чтобы сделать то же самое, а затем, когда SP3 был выпущен, функция objProcess.Terminate () просто отказывалась работать на некоторых машинах. Что бы мы ни делали, это просто замерзло. Это произошло примерно на 10% наших тестовых машин, поэтому мы были вынуждены найти альтернативное решение (кто знает, на скольких клиентах оно могло замерзнуть!)

Моим первым открытием была встроенная (начиная с Windows 2000) команда TASKKILL Например: TASKKILL /IM app.exe /F, но, похоже, что для уничтожения процесса используются те же средства, что и в VBScript, этот метод также завершится ошибкой.

Итак, теперь мы используем инструмент pskill.exe от sysinternals, вам нужно использовать переключатель командной строки для подавления запроса о лицензионном соглашении, но кроме этого, это был самый надежный способ уничтожения работающего EXE, который я нашел.

Конечно, лучшим решением было бы создать свой собственный EXE или DLL, чтобы сделать это, если бы вы немного узнали C ++;)

1 голос
/ 23 сентября 2009

Недостаточно просто завершить процессы, поскольку это не приводит к очистке области уведомлений Windows (однако Windows будет очищать значок без соответствующего процесса, когда наведется указатель мыши). Еще одна причина, по которой внезапное завершение работы приложений, как правило, лучше всего резервировать для отладки. К сожалению, более правильное решение также является более сложным. Вы можете создать именованное событие в приложении и зарегистрировать метод обратного вызова, который будет вызываться при его установке. Обратный вызов закроет приложение. Затем вы должны написать пользовательское действие, которое установит событие и будет ждать завершения процесса.

Если вам требуется поддержка отмены (например, пользователю предлагается сообщить, что он сохранил несохраненные изменения и решает не отменять), вы можете использовать другое именованное событие, чтобы указать на это, поэтому пользовательское действие может ожидать либо завершения процесса, либо событие отмены, в зависимости от того, что наступит раньше.

0 голосов
/ 08 января 2011

Если ваш app.exe был создан дома, вы можете добавить командную строку, которая скажет ему убить ту, которая работает в данный момент. Когда передается эта командная строка, он отправляет этому первому экземпляру программы сообщение или что-то, что говорит ему выйти, а затем зависает, ожидая, пока этот первый экземпляр программы не завершится. После этого установщик сможет запустить программу с переключателем kill и знать, что его первоначальный экземпляр исчез, когда возвращается экземпляр переключенного уничтожения.

0 голосов
/ 31 октября 2008

Вы можете вставить элементы 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
...