我正在开发一个启动Powershell脚本以设置和启动服务流程(不是正式的Windows服务)的应用程序。我希望能够向这些Powershell进程及其子进程发送ctrl + c信号,以彻底关闭它们。
当我创建Powershell进程时,我设置了CREATE_NEW_PROCESS_GROUP
,它隐式调用SetConsoleCtrlHandler(NULL,TRUE)
,它有效地为创建的进程及其子进程关闭ctrl + c。我无法使用ctrl + break,因为这会使powershell进入 Debug模式。因此,在启动的Powershell进程中,当我想停止该进程树时,我调用SetConsoleCtrlHandler(NULL,FALSE)
重新打开ctrl + c,然后让我的应用程序调用GenerateConsoleCtrlEvent
将ctrl + c事件发送到powershell的进程组。这可以完美运行,但有一个主要缺陷。
如果我在运行应用程序的控制台中手动键入ctrl + c,则我的应用程序将拦截ctrl + c,然后为每个powershell进程调用GenerateConsoleCtrlEvent
。这似乎运作良好,但只有第一次。
我的应用程序退出后,似乎我在该控制台中运行的任何程序的ctrl + c都已关闭。如果我运行PING
或自己的应用程序,则ctrl + c不会执行任何操作,并且不确定如何进一步调试。
有趣的是,我有时会在conhost.exe中看到进程浏览器中死掉的powershell进程的句柄。如果在进程资源管理器中关闭这些句柄,SOMETIMES ctrl + c会回来。因此,我怀疑有一些句柄泄漏,但是这种观察结果并不一致,因此我小心释放应用程序中的过程句柄。
关于可能导致控制台的ctrl + c信号吞咽的任何想法?
最佳答案
看来,在用户调用ctrl + c之后触发GenerateConsoleCtrlEvent
会使 shell 进入这种奇怪状态。当用户输入ctrl + c时,实际上我的应用程序不需要调用GenerateConsoleCtrlEvent
,因为GenerateConsoleCtrlEvent广播到控制台中的每个进程。不幸的是,让我的应用程序在拦截ctrl + c时放弃GenerateConsoleCtrlEvent
容易做起来难,但并非不可能。
令我感到不安的是,我没有找到任何文档或信息表明在键入ctrl + c后触发GenerateConsoleCtrlEvent
具有这种奇怪的效果,但也许这篇文章会对其他人有所帮助。
如果有人对导致此状态被触发的原因有更深入的了解,或者有其他避免此状态并使 shell 对GenerateConsoleCtrlEvent
更具 flex 的提示,请在此处发布另一个答案。