私はGenerateConsoleCtrlEvent
仕事に就こうとしています。これは私が思いついた最小限の例です:
#include <Windows.h>
static BOOL WINAPI handler(DWORD CtrlType)
{
return TRUE;
}
int main()
{
if (!SetConsoleCtrlHandler(&handler, TRUE))
{
throw 1;
}
STARTUPINFO si = {0};
DWORD dwStartupFlags = 0;
PROCESS_INFORMATION pi;
if (!CreateProcess(
NULL,
"cmd.exe",
NULL,
NULL,
FALSE,
dwStartupFlags,
NULL, // environ
NULL, // cwd
&si,
&pi))
{
throw 1;
}
CloseHandle(pi.hThread);
DWORD exitCode;
while(true)
{
switch (WaitForSingleObject(pi.hProcess, 1000 * 10))
{
case WAIT_TIMEOUT:
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
//WaitForSingleObject(pi.hProcess, INFINITE);
break;
case WAIT_OBJECT_0:
GetExitCodeProcess(pi.hProcess, &exitCode);
return exitCode;
}
}
return -1;
}
だから私はそれを起動し、何かを入力して(改行なしで)、10秒待ちます。デバッガーに Ctrl-C イベントが表示されます。コンソールは、Ctrl-C が無効であることを示しています。
私はこれに問題を突き止めました: メインの cmd.exe スレッドは を呼び出しますReadConsoleW
。を使用したテスト プログラムではGenerateConsoleCtrlEvent
、これは返されません。Ctrl-C を押すと戻り*lpNumberOfCharsRead==0
ます。
GenerateConsoleCtrlEvent
を使用して新しいスレッドを開始しますkernel32!CtrlRoutine
。デバッガーを使用してこのスレッドをフリーズしても、cmd.exe は Ctrl-C が押されたかのように動作します。実際、 return キーを押した後に戻る*lpNumberOfCharsRead==NULL
ときに設定すると、cmd.exe をだまして Ctrl-C が押されたと信じ込ませることができます。ReadConsoleW
cmd.exe
の動作は一意ではありません。Python.exe の読み取りは Ctrl-C ではすぐに戻りますが、 では戻りませんGenerateConsoleCtrlEvent
。Python.exe はReadFile
. (Enter キーを押した後、Python.exe は KeyboardInterrupt を認識します。)
ReadConsoleW
問題は、Ctrl-C を押すとすぐに返されるのに、GenerateConsoleCtrlEvent
呼び出されたときに返されないのはなぜですか? 私が知る限り、Windows 7 では、Ctrl-C を押すと、 がconhost.exe
と通信しcsrss.exe
、 が を呼び出すメッセージが送信さNtCreateThreadEx
れますkernel32!CtrlRoutine
。Ctrl-C を押しても他に何もしないようです。しかし、何が原因ReadConsoleW
で戻ってくるのでしょうか?