如何优雅地终止一个进程?

发布于 2024-08-17 20:33:22 字数 393 浏览 2 评论 0原文

我想终止多个进程,但我想让每个进程都有机会保存其数据,询问用户有关保存文件的信息,甚至忽略关闭请求。

所以 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

绝不放开 2024-08-24 20:33:22

EnumWindows 枚举进程中的所有顶级窗口。 GetWindowThreadProcessId 获取每个线程的进程和 Id。

您现在有足够的信息来正常关闭任何 GUI 应用程序。

您可以向任何您想要关闭的窗口发送 WM_CLOSE 消息。许多窗口都会处理WM_CLOSE来提示用户保存文档。您可以使用PostThreadMessage向发现的线程发送WM_QUIT消息以导致消息循环终止。

如果应用程序不响应 WM_CLOSEWM_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 handle WM_CLOSE to prompt the user to save documents.You can send a WM_QUIT message using PostThreadMessage 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 to WM_CLOSE or WM_QUIT requests you're back in TerminateProcess 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.

狼亦尘 2024-08-24 20:33:22

我不太确定 win32 api,但你可以通过 shell 执行 taskkill 命令行函数。

taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe

/f 开关将强制终止,但不使用它只是发送终止信号,以便应用程序正常关闭。

I'm not too sure about the win32 apis but you could shell execute the taskkill command line function.

taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe

The /f switch would force the kill but not using it just sends the termination signal so the application closes gracefully.

雪化雨蝶 2024-08-24 20:33:22

请参阅 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

墨洒年华 2024-08-24 20:33:22

要添加到 Chris Becke 关于优雅终止控制台进程的回答:

应在控制台应用程序中处理此事件以正常终止。

To add to Chris Becke's answer about terminating gracefully terminating console process:

This event should be handled in the console application for graceful termination.

迷迭香的记忆 2024-08-24 20:33:22

使用 EndTask API 函数。它与任务管理器使用的功能相同。

BOOL EndTask(      
    HWND hWnd,
    BOOL fShutDown,
    BOOL fForce
);

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.

BOOL EndTask(      
    HWND hWnd,
    BOOL fShutDown,
    BOOL fForce
);

http://msdn.microsoft.com/en-us/library/ms633492(VS.85).aspx

清浅ˋ旧时光 2024-08-24 20:33:22

您可以使用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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文