我正在开发一个应用程序,该应用程序启动PowerShell脚本来设置和启动服务进程(不是正式的Windows服务)。我希望能够将 ctrl + c 信号发送到这些powershell进程及其子进程,以便彻底关闭它们。
当我创建powershell进程时,我设置了CREATE_NEW_PROCESS_GROUP
隐式调用SetConsoleCtrlHandler(NULL,TRUE)
,它有效地关闭了创建进程的 ctrl + c 它的孩子。我无法使用 ctrl + break ,因为这会将PowerShell置于调试模式。所以在我启动的powershell流程中,我调用SetConsoleCtrlHandler(NULL,FALSE)
重新打开 ctrl + c ,让我的应用程序调用{{1}}发送<当我想要停止该进程树时,kbd> ctrl + c 事件到powershell的进程组。这很有效,但有一个主要缺陷。
如果我在运行我的应用程序的控制台中键入ctrl + c,我的应用程序会拦截 ctrl + c 然后为每个调用GenerateConsoleCtrlEvent
powershell过程。这似乎运作良好,但仅限第一次。
我的应用程序退出后,似乎 ctrl + c 现在在我在该控制台中运行的任何程序都关闭了。如果我运行GenerateConsoleCtrlEvent
或我自己的应用程序, ctrl + c 什么都不做,我不确定如何进一步调试。
有趣的是,我有时会在进程资源管理器中看到conhost.exe中已知的powershell进程中的句柄。如果我在进程资源管理器中关闭这些句柄,则会返回SOMETIMES ctrl + c 。所以我怀疑一些句柄泄漏,但这种观察结果不一致,我小心翼翼地在我的应用程序中释放我的进程句柄。
有关可能导致我的控制台的 ctrl + c 信号被吞下的任何想法?
答案 0 :(得分:2)
看起来在用户调用 ctrl + c 之后触发GenerateConsoleCtrlEvent
是将shell置于这种奇怪状态的原因。当用户输入 ctrl + c 时,我的应用程序实际上不需要调用GenerateConsoleCtrlEvent
,因为GenerateConsoleCtrlEvent会广播到控制台中的每个进程。不幸的是,我的应用程序放弃GenerateConsoleCtrlEvent
时拦截 ctrl + c 说起来容易做起来难,但并非不可能。
令人不安的是,我没有发现任何文档或信息表明在键入的 ctrl + c 之后触发GenerateConsoleCtrlEvent
有这种奇怪的效果但是这个帖子可能会帮助别人。
如果有人深入了解为什么会触发此状态的详细信息,或者有其他方法可以避免这种情况并使shell更具弹性GenerateConsoleCtrlEvent
,请在此处发布另一个答案。