我想终止一些进程,但我想让每个进程都有机会保存其数据,询问用户是否保存文件,甚至忽略关闭请求。
所以TerminateProcess
是不可能的,因为它会立即杀死这个过程。另一种方法是使用SendMessage
/ PostMessage
将WM_CLOSE
发送到主窗口,遗憾的是我对进程的窗口一无所知,我只有进程ID ,所以FindWindow
也无济于事。有没有其他方法可以找到进程的主窗口?
换句话说: 有没有办法优雅地终止任何进程,就像任务管理器点击“结束任务”时那样? (而不是“结束过程”)
答案 0 :(得分:25)
EnumWindows枚举进程中的所有顶级窗口。 GetWindowThreadProcessId获取每个帖子的进程和ID。
您现在有足够的信息可以正常关闭任何GUI应用程序。
您可以将WM_CLOSE
条消息发送到您要关闭的任何窗口。许多窗口处理WM_CLOSE
以提示用户保存文档。您可以使用WM_QUIT
向发现的线程发送PostThreadMessage
消息,以使消息循环终止。
不允许用户代码从其他应用或线程调用DestroyWindow
到Windows ...如果应用未响应WM_CLOSE
或WM_QUIT
请求,则表示您已退回在TerminateProcess
土地。
这不会关闭控制台应用程序,因为应用程序进程和拥有该窗口的进程是不同的。
没有真正的方法可以在Windows上正常关闭控制台应用程序。他们需要支持某种优雅的关闭机制。
答案 1 :(得分:15)
我对win32 apis不太了解,但你可以shell执行taskkill
命令行函数。
taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe
/ f开关会强制终止但不使用它只是发送终止信号,以便应用程序正常关闭。
答案 2 :(得分:13)
请参阅MSKB Q178893 How To Terminate an Application "Cleanly" in Win32
答案 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
处理消息。