Можно ли обнаружить «конечный процесс» извне? - PullRequest
2 голосов
/ 15 сентября 2011

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

Ответы [ 4 ]

1 голос
/ 16 сентября 2011

Согласно документации, ExitProcess вызывает точку входа всех загруженных DLL с помощью DLL_PROCESS_DETACH, тогда как TerminateProcess - нет.(Выход из основной функции приводит к вызову ExitProcess, как и большинство необработанных исключений .)

Возможно, вы также захотите взглянуть на Восстановление приложений и перезапуск .

1 голос
/ 15 сентября 2011

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

Когда вы закончите, не забудьте позвонить CloseHandle.Объект процесса не будет полностью удален из ОС до тех пор, пока все его дескрипторы не будут закрыты, поэтому вы потеряете ресурсы, если забудете вызвать CloseHandle.

Обратите внимание, что нет никакого способа различитьпроцесс завершается нормально или принудительно завершается.Даже если у вас есть соглашение о том, что ваша программа обычно завершает работу только с состоянием 0 (успех) или 1 (сбой), какой-то другой процесс может вызвать TerminateProcess(YourProcess, 1), и это будет неотличимо от вашего обычного режима сбоя.

1 голос
/ 15 сентября 2011

Возможно, есть лучший способ - но как насчет использования простого флага?

Естественно, вам нужно сохранить этот флаг где-нибудь за пределами памяти процесса / программы - например, реестра, базы данных илифайловая система.По сути, когда приложение запускается, вы устанавливаете флаг «True», когда приложение выключается обычным способом, вы устанавливаете флаг «False».

Каждый раз, когда приложение запускается, вы можете проверитьфлаг, чтобы увидеть, если он не был выключен правильно в прошлый раз, когда он был выполнен.

0 голосов
/ 15 сентября 2011

Одним из вариантов может быть создание «сторожевого» приложения (возможно, установленного как служба), которое отслеживает события WMI для остановки процесса с помощью класса ManagementEventWatcher (в пространстве имен System.Management).

Вы можете запросить смерть вашего процесса через определенный промежуток времени или придумать какой-нибудь управляемый событиями способ оповещения о кончине вашего процесса.

Вот своего рода пример (хотя это на C #, хотя), который мог бы начать вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...