微软文档指出:
如果使用SetConsoleMode标志在屏幕缓冲区句柄上设置了ENABLE_VIRTUAL_TERMINAL_PROCESSING标志,下列终端序列将被拦截并写入输出流中。您可以使用GetConsoleMode和SetConsoleMode标志配置此行为。
因此,我编写了一个简单的C程序来更改控制台模式,然后作为管道或启动另一个进程并等待(抱歉,这只是测试代码)。
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
int _tmain(int argc, TCHAR *argv[]){
DWORD dwOldMode, dwMode ;
HANDLE hStdout;
int c;
STARTUPINFO si;
PROCESS_INFORMATION pi;
hStdout = GetStdHandle( STD_OUTPUT_HANDLE );
if (! GetConsoleMode( hStdout, &dwOldMode ) ) {
return 1;
}
dwMode = dwOldMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (! SetConsoleMode( hStdout, dwMode ) ){
CloseHandle( hStdout );
return 2;
}
if( argc < 2 ) {
while ( EOF != (c = getchar()) ) putchar( c );
} else {
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess(NULL, argv[1], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi )){
printf( "CreateProcess failed (%d).\n", GetLastError() );
return 3;
}
WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
SetConsoleMode( hStdout, dwOldMode );
CloseHandle( hStdout );
return 0;
};
使用 mingw/gcc
编译生成了 run.exe
。结果如下:
![测试会话的输出截图](https://istack.dev59.com/LrNjF.webp)
现在,处理来自 cscript
和 findstr
的输出并解释转义序列。
另外,如果我运行 cmd.exe
而不是单独运行这些程序
![重定向 cmd.exe 的输出截图](https://istack.dev59.com/C6kSK.webp)
由于我没有更改 findstr.exe
、cscript.exe
或 cmd.exe
的代码,只是它们所工作的环境不同,因此看起来:
既不是 cscript
也不是 findstr
配置/更改控制台缓冲区配置
一些内部 cmd
命令更改了缓冲区配置(我忘记在截图中包含它了,但 copy test.txt con
和 prompt
也可以工作),或者正如你所说,它们使用了不同的输出方法
对于将数据写入标准输出流的应用程序,唯一的要求是正确配置控制台输出缓冲区模式。
不,我不知道如何通过纯批处理启用它。