Как изящно прекратить процесс?
Я хочу прервать ряд процессов, но я хочу дать каждому процессу возможность сохранить его данные, спросить пользователя о сохранении файла и даже игнорировать запрос на закрытие.
So TerminateProcess
не может быть и речи, потому что он мгновенно убивает процесс. Другим способом было бы использовать SendMessage
/PostMessage
для отправки WM_CLOSE
в главное окно, к сожалению, я ничего не знаю о окнах процессов, у меня есть только идентификатор процесса, поэтому FindWindow
doesn Не помогите. Есть ли другой способ найти основные окна процесса?
Другими словами:
Есть ли способ закончить любой процесс изящно, как это делает диспетчер задач, когда вы нажимаете " Завершить задачу"? (а не "Конечный процесс" )
Ответы
Ответ 1
EnumWindows перечисляет все окна верхнего уровня в процессе. GetWindowThreadProcessId получает процесс и идентификатор каждого потока.
Теперь у вас достаточно информации, чтобы изящно закрыть любое приложение с графическим интерфейсом.
Вы можете отправлять сообщения WM_CLOSE
в любое окно, которое хотите закрыть. Многие окна обрабатывают WM_CLOSE
, чтобы побудить пользователя сохранить документы. Вы можете отправить сообщение WM_QUIT
с помощью PostThreadMessage
обнаруженным потокам, чтобы завершить цикл обработки сообщений.
Пользовательский код не может вызывать DestroyWindow
из другого приложения или потока в окнах... если приложение не отвечает на запросы WM_CLOSE
или WM_QUIT
, вы вернулись на землю TerminateProcess
.
Это не приведет к закрытию консольных приложений, поскольку процесс приложения и процесс, которому принадлежит окно, отличаются.
Обратитесь к T.s. Арун ответьте ниже для правильного метода работы с консольными приложениями.
Ответ 2
Я не слишком уверен в win32 apis, но вы можете использовать команду taskkill
для командной строки.
taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe
Переключатель/f заставит убивать, но не использует его, просто отправляет сигнал завершения, чтобы приложение закрывалось изящно.
Ответ 3
См. MSKB Q178893 Как завершить приложение "Чисто" в Win32
Ответ 4
Чтобы добавить к Крису Бекке ответ о прекращении изящного завершения консольного процесса.
AttachConsole() для присоединения к консольному приложению и отправки события прерывания управления, аналогично нажатию клавиш CTRL + C в командной строке.
Использование GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, processID).
Это событие управления должно быть обработано в консольном приложении для корректного завершения.
Ответ 5
Используйте функцию EndTask API. Это та же самая функция, которая используется диспетчером задач.
BOOL EndTask(
HWND hWnd,
BOOL fShutDown,
BOOL fForce
);
http://msdn.microsoft.com/en-us/library/ms633492(VS.85).aspx
Ответ 6
Вы можете использовать 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