Как изящно прекратить процесс?
Я хочу завершить несколько процессов, но я хочу дать каждому процессу возможность сохранить свои данные, спросить пользователя о сохранении файла и даже игнорировать запрос на закрытие.
Так TerminateProcess
не может быть и речи, потому что это убивает процесс мгновенно. Другой способ будет использовать SendMessage
/PostMessage
отправить WM_CLOSE
к главному окну, к сожалению, я ничего не знаю о окнах процессов, у меня есть только идентификатор процесса, поэтому FindWindow
тоже не помогает Есть ли другой способ найти главные окна процесса?
Другими словами: есть ли способ завершить любой процесс изящно, как это делает менеджер задач, когда вы нажимаете "Завершить задачу"? (а не "Завершить процесс")
5 ответов
EnumWindows перечисляет все окна верхнего уровня в процессе. GetWindowThreadProcessId получает процесс и идентификатор каждого потока.
Теперь у вас достаточно информации, чтобы изящно закрыть любое приложение с графическим интерфейсом.
Ты можешь отправить WM_CLOSE
сообщения в любое окно, которое вы хотите закрыть. Многие окна обрабатывают WM_CLOSE
предложить пользователю сохранить документы. Вы можете отправить WM_QUIT
использование сообщений PostThreadMessage
в обнаруженные потоки, чтобы заставить цикл сообщений завершиться.
Пользовательский код не может звонить DestroyWindow
из другого приложения или потока в Windows... если приложение не отвечает на WM_CLOSE
или же WM_QUIT
просит вас вернуться TerminateProcess
земельные участки.
Это не закроет консольные приложения, так как процесс приложения и процесс, которому принадлежит окно, отличаются.
Нет реального способа изящно закрыть консольные приложения в Windows. Им нужно поддерживать какой-то изящный закрытый механизм.
Я не слишком уверен насчет apis win32, но вы можете выполнить taskkill
функция командной строки.
taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe
Ключ /f принудительно уничтожает, но не используя его, просто отправляет сигнал завершения, поэтому приложение корректно закрывается.
Чтобы добавить к Chris Becke ответ о прекращении изящного завершения консольного процесса.
AttachConsole () для присоединения к консольному приложению и отправки события прерывания управления, аналогично нажатию CTRL+C в командной строке.
Использование GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, processID).
Это событие управления должно обрабатываться в консольном приложении для корректного завершения.
Используйте функцию EndTask API. Это та же функция, которая используется диспетчером задач.
BOOL EndTask(
HWND hWnd,
BOOL fShutDown,
BOOL fForce
);
http://msdn.microsoft.com/en-us/library/ms633492(VS.85).aspx
Вы можете использовать taskkill /im your_program.exe, чтобы отправить сигнал завершения в приложение. Это вызовет WM_CLOSE для очереди сообщений Windows. Вы можете использовать либо https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx либо
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmessage
обработать сообщение.
Прошу сослаться аналогичный ответ Win32 API аналог отправки / отлова SIGTERM