Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何使GenerateConsoleElement与cmd.exe一起工作_Windows_Winapi_Cmd_Console Application_Windows Console - Fatal编程技术网

Windows 如何使GenerateConsoleElement与cmd.exe一起工作

Windows 如何使GenerateConsoleElement与cmd.exe一起工作,windows,winapi,cmd,console-application,windows-console,Windows,Winapi,Cmd,Console Application,Windows Console,我正在努力使generateConsoleControlevent正常工作。这是我想到的最简单的例子: #include <Windows.h> static BOOL WINAPI handler(DWORD CtrlType) { return TRUE; } int main() { if (!SetConsoleCtrlHandler(&handler, TRUE)) { throw 1; } STARTU

我正在努力使
generateConsoleControlevent
正常工作。这是我想到的最简单的例子:

#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;
}
#包括
静态布尔WINAPI处理程序(DWORD CtrlType)
{
返回TRUE;
}
int main()
{
if(!setConsoletrlHandler(&handler,TRUE))
{
投掷1枚;
}
STARTUPINFO si={0};
DWORD dwStartupFlags=0;
处理信息;
如果(!CreateProcess(
无效的
“cmd.exe”,
无效的
无效的
假,,
德国国旗,
NULL,//环境
NULL,//cwd
&嗯,
&(圆周率)
{
投掷1枚;
}
CloseHandle(pi.hThread);
德沃德出口代码;
while(true)
{
开关(WaitForSingleObject(pi.hProcess,1000*10))
{
案例等待超时:
GenerateConsoleCtrlEvent(CTRL_C_事件,0);
//WaitForSingleObject(pi.hProcess,无限);
打破
案例等待对象0:
GetExitCodeProcess(pi.hProcess和exitCode);
返回exitCode;
}
}
返回-1;
}
所以我启动它,输入一些东西(没有换行符),然后等待10秒钟。调试器显示Ctrl-C事件。控制台显示Ctrl-C无效

我找到了这个问题:主cmd.exe线程调用
ReadConsoleW
。在带有
generateConsoleControlevent
的测试程序下,不会返回。按Ctrl-C键确实会使其返回,并且
*lpNumberOfCharsRead==0

generateConsoleControlevent
使用
kernel32启动一个新线程!CtrlRoutine
。如果使用调试器冻结此线程,cmd.exe的行为仍与按下Ctrl-C时的行为相同。事实上,如果在按下返回键后返回
ReadConsoleW
时设置
*lpNumberOfCharsRead==NULL,则可以欺骗cmd.exe,使其相信按下了Ctrl-C

cmd.exe
在行为上不是唯一的:Python.exe的读取在Ctrl-C时立即返回,但在
generateConsoleControlEvent
时不会返回。Python.exe使用
ReadFile
。(Python.exe在按enter键后会注意到键盘中断。)


所以问题是:为什么按下Ctrl-C键时,
ReadConsoleW
会立即返回,而在调用
generateConsoleControlevent
时却不会返回?据我所知,在Windows 7上,按Ctrl-C发送消息,这些消息由
conhost.exe
读取,后者与
csrss.exe
通信,后者使用
kernel32调用
NtCreateThreadEx
!CtrlRoutine
。我看不出当您按下Ctrl-C时它会做任何其他事情。但是是什么导致
ReadConsoleW
返回?

SetConsoleMode()winapi函数的ENABLE\u PROCESSED\u输入选项标志是相关的。它允许程序指定是希望看到Ctrl+C本身,还是让系统来处理它。cmd.exe的此标志绝对处于禁用状态。因为按Ctrl+C并不能终止它。我想,试着启动cmd.exe之外的东西吧?另请参见测试程序中的内容,如果您将
cmd.exe
Python.exe
交换,则其行为类似:
generateConsoleControlEvent
不会立即生效,但
Python.exe
会在按enter键后注意到Ctrl+C。我不认为
cmd.exe
在这里是独一无二的。