4

私は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で戻ってくるのでしょうか?

4

0 に答える 0