如何优雅地终止一个进程?
我想终止多个进程,但我想让每个进程都有机会保存其数据,询问用户有关保存文件的信息,甚至忽略关闭请求。
所以 TerminateProcess
是不可能的,因为它会立即终止进程。另一种方法是使用 SendMessage
/PostMessage
向主窗口发送 WM_CLOSE
,不幸的是我对 Windows 的窗口一无所知对于进程,我只有进程 ID,所以 FindWindow 也没有帮助。还有其他方法可以找到进程的主窗口吗?
换句话说: 有没有办法像 Windows 7 任务管理器单击“结束任务”时那样优雅地终止任何进程? (而不是“结束进程”)
I want to terminate a number of processes, but I want to give each process the chance to save its data, ask the user about saving a file and even ignore the close request.
So TerminateProcess
is out of the question, because it kills the process instantly. Another way would be to use SendMessage
/PostMessage
to send a WM_CLOSE
to the main window, unfortunately I don't know anything about the windows of the processes, I only have the process id, so FindWindow
doesn't help either. Is there any other way to find the main windows of a process?
In other words:
Is there any way to terminate any process gracefully just like the Windows 7 task manager did when you clicked on "End Task"? (and not "End Process")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
EnumWindows 枚举进程中的所有顶级窗口。 GetWindowThreadProcessId 获取每个线程的进程和 Id。
您现在有足够的信息来正常关闭任何 GUI 应用程序。
您可以向任何您想要关闭的窗口发送
WM_CLOSE
消息。许多窗口都会处理WM_CLOSE
来提示用户保存文档。您可以使用PostThreadMessage
向发现的线程发送WM_QUIT
消息以导致消息循环终止。如果应用程序不响应
WM_CLOSE
或WM_QUIT
,则用户代码不允许从不同的应用程序或线程调用DestroyWindow
到窗口... > 请求您返回TerminateProcess
陆地。这不会关闭控制台应用程序,因为应用程序进程和拥有该窗口的进程是不同的。
请参阅下面 Ts Arun 的回答,了解处理控制台应用程序的正确方法。
EnumWindows enumerates all the top level windows in a process. GetWindowThreadProcessId gets the process and Id of each thread.
You now have enough information to gracefully close any GUI application.
You can send
WM_CLOSE
messages to any window you wish to close. Many windows handleWM_CLOSE
to prompt the user to save documents.You can send aWM_QUIT
message usingPostThreadMessage
to the discovered threads to cause the message loop to terminate.User code is not allowed to call
DestroyWindow
from a different app or thread to the windows... if the app does not respond toWM_CLOSE
orWM_QUIT
requests you're back inTerminateProcess
land.This will not close console applications as the application process, and process that owns the window, are different.
Refer to T.s. Arun's answer below for the correct method for dealing with console applications.
我不太确定 win32 api,但你可以通过 shell 执行
taskkill
命令行函数。/f 开关将强制终止,但不使用它只是发送终止信号,以便应用程序正常关闭。
I'm not too sure about the win32 apis but you could shell execute the
taskkill
command line function.The /f switch would force the kill but not using it just sends the termination signal so the application closes gracefully.
请参阅 MSKB Q178893 如何在 Win32 中“干净地”终止应用程序。基本上发送 WM_CLOSE 到目标应用程序的所有窗口以允许宽限关闭,然后使用 TerminateProcess 强制终止应用程序
See MSKB Q178893 How To Terminate an Application "Cleanly" in Win32. Basically send send WM_CLOSE to all windows of the target app to allow a grace shutdown, before force kill the app with TerminateProcess
要添加到 Chris Becke 关于优雅终止控制台进程的回答:
AttachConsole()
附加到控制台应用程序并GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, processID)
。应在控制台应用程序中处理此事件以正常终止。
To add to Chris Becke's answer about terminating gracefully terminating console process:
AttachConsole()
to attach to the console application andGenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, processID)
.This event should be handled in the console application for graceful termination.
使用 EndTask API 函数。它与任务管理器使用的功能相同。
http://msdn.microsoft.com/en-us /library/ms633492(VS.85).aspx
Use the EndTask API function. It is the same function that is used by task manager.
http://msdn.microsoft.com/en-us/library/ms633492(VS.85).aspx
您可以使用taskkill /im your_program.exe向应用程序发送终止信号。它将触发 Windows 消息队列的 WM_CLOSE。您可以使用
任何一个
https://msdn.microsoft .com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
或
https://learn.microsoft.com /en-us/windows/desktop/api/winuser/nf-winuser-getmessage
来处理消息。
请参考类似的答案 发送/捕获 SIGTERM 的 Win32 API 模拟< /a>
You can use taskkill /im your_program.exe to send a termination signal to the application. It will trigger a WM_CLOSE to windows message queue. You can use
Either
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
or
https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmessage
to process the message.
Please refer a similar answer Win32 API analog of sending/catching SIGTERM