Как остановить работающий процесс во время деинсталляции на основе MSI?

Я использую 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 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам