windows - Windows 上的 CTRL_C_EVENT 与 CTRL_BREAK_EVENT 与 TerminateProcess

标签 windows

我看过很多关于 Windows 的 TerminateProcess API 的讨论。另外,我了解到还有 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 事件。

我的问题是,它们之间有什么区别?

最佳答案

TerminateProcess is insta-death 。该进程不会看到它的到来,并且会眨眼间消失,而不知道是什么击中了它:

TerminateProcess is the low-level process killing function. It bypasses DLL_PROCESS_DETACH and anything else in the process. Once you kill with TerminateProcess, no more user-mode code will run in that process. It’s gone. Do not pass go. Do not collect $200.

~ Raymond Chen (I updated the links though)

相反,Ctrl+C 和 Ctrl+Break 被处理为信号1并且可以使用react。这些组合键会触发相应的信号,但还有一个功能 GenerateConsoleCtrlEvent 可用于触发它们2

不过,它们的处理方式略有不同。 Ctrl+Break始终作为信号处理,而 Ctrl+C默认作为信号处理,但应用程序可能会更改此行为,将其视为常规键盘输入或完全忽略。详细说明了如何实现这一点in the docs .

“作为信号处理”含义如下:

The system creates a new thread in each client process to handle the event. The thread raises an exception if the process is being debugged. The debugger can handle the exception or continue with the exception unhandled.

...和:

[A console control handler is] An application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function.

默认有console control handlers已安装,但您可以随意更改它们。默认值将对 Ctrl+C 和 Ctrl+Break 使用react并终止进程,但使用 ExitProcess 而不是TerminateProcess 。与 TerminateProcess 的使用不同这构成了立即的 rugpull,这将给进程中的某些清理操作在完全终止之前有机会运行,例如 DLL_PROCESS_DETACH DllMain functions 中的处理程序和 TLS callbacks .

引用文献和进一步阅读:


脚注:

1:从广义上讲,“作为信号处理”仅意味着“可以有一些用户提供的函数获得有关此事件的通知,并允许对其采取行动所期望的”。请注意,您从 *nixes 中了解到的广义信号在 Windows 中并不作为概念存在。在某些地方,文档引用 *nix 式的信号名称,例如 SIGINTSIGBREAK在本例中,但这可能只是为了让您更容易理解(如果您来自 *nix 背景)。在不同的背景下可能会发生不同的事件,并且他们有不同的 react 方式。这里我们讨论的是控制台控制处理程序可以接收的控制台事件(这些 Ctrl+C 和 Ctrl+Break“信号”将在控制台控制处理程序的 fdwCtrlType 参数中显示为 CTRL_C_EVENTCTRL_BREAK_EVENT ,但控制台控制处理程序也可以处理其他事件,例如 CTRL_CLOSE_EVENT ),但在 *nix 世界中也将是“信号”的其他事件以完全不同的方式处理 - 例如,访问冲突将是 SIGSEGV在 *nix 中需要 UnhandledExceptionFilter 来处理,并且不存在 SIGTERM 的概念根本没有(这取决于您想要要求终止的程序类型 - 如果是 GUI 程序,最接近的事情是向主窗口发送 WM_CLOSE 消息,如果您能弄清楚那是哪个窗口,如果是在 Windows 服务管理器中注册的后台服务有一个专用的“停止”命令,如果是控制台程序,它可以是控制台关闭事件,当您单击控制台窗口的关闭按钮时也会触发该事件等)。因此,不要尝试在这里应用您关于信号在其他操作系统上的作用的知识。

2:但是,要使此功能正常工作,调用者需要与接收者位于同一控制台进程组中。因此,如果您想从外部进程发送此消息,您首先需要一些技巧,例如拥有一个辅助进程,其唯一的工作是将自身附加到目标的控制台,然后“从内部”触发事件。

关于windows - Windows 上的 CTRL_C_EVENT 与 CTRL_BREAK_EVENT 与 TerminateProcess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72258181/

相关文章:

windows - 当中央存储库位于 Windows 文件共享上时,与多个用户一起使用 git 是否安全?

c# - Web 浏览器控件忽略 FEATURE_BROWSER_EMULATION reg 条目

windows - wmic cpu get LoadPercentage 总是返回空值

c++ - 在获取DLL_PROCESS_DETACH之前需要DLL已关闭的通知

c# - 在 C# 程序集中处理事件

windows - 如何使用命令提示符 (cmd) 在 Windows 中列出文件。我试过在 Linux 中使用 ' ls ' 但它显示错误?

c++ - select() 可以与阻塞套接字一起使用吗?

java - Java 可以控制其他程序的窗口位置吗?

使用 native 库启动 exe 的 c++ 隐形应用程序

windows - 如何在 Windows 的 sublime text 3 中设置 Gosublime?