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
在这里是独一无二的。