Как изящно прекратить процесс?

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

Так 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 принудительно уничтожает, но не используя его, просто отправляет сигнал завершения, поэтому приложение корректно закрывается.

См. MSKB Q178893 Как завершить приложение "чисто" в Win32

Чтобы добавить к 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

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