如何优雅地终止进程?

时间:2010-01-13 09:53:56

标签: winapi process

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

所以TerminateProcess是不可能的,因为它会立即杀死这个过程。另一种方法是使用SendMessage / PostMessageWM_CLOSE发送到主窗口,遗憾的是我对进程的窗口一无所知,我只有进程ID ,所以FindWindow也无济于事。有没有其他方法可以找到进程的主窗口?

换句话说: 有没有办法优雅地终止任何进程,就像任务管理器点击“结束任务”时那样? (而不是“结束过程”)

6 个答案:

答案 0 :(得分:25)

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

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

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

不允许用户代码从其他应用或线程调用DestroyWindow到Windows ...如果应用未响应WM_CLOSEWM_QUIT请求,则表示您已退回在TerminateProcess土地。

这不会关闭控制台应用程序,因为应用程序进程和拥有该窗口的进程是不同的。

没有真正的方法可以在Windows上正常关闭控制台应用程序。他们需要支持某种优雅的关闭机制。

答案 1 :(得分:15)

我对win32 apis不太了解,但你可以shell执行taskkill命令行函数。

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

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

答案 2 :(得分:13)

答案 3 :(得分:3)

添加关于终止正常终止控制台进程的Chris Becke答案。

AttachConsole()附加到控制台应用程序并发送控制中断事件,类似于在命令提示符中按 CTRL + C

使用GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,processID)。

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

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:0)

您可以使用 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 analog of sending/catching SIGTERM