Как использовать escape-последовательности ANSI с CSCRIPT в Windows 10?

Я пытаюсь использовать новые возможности escape-последовательности VT100 ANSI, доступные в консоли Windows 10 с CSCRIPT (JScript). Но я не могу заставить его работать.

вот действительно простой скрипт JScript:

2 ответов


документация MS государства

следующие последовательности терминалов перехватываются хостом консоли при записи в выходной поток, если ENABLE_VIRTUAL_TERMINAL_PROCESSING флаг устанавливается на дескрипторе буфера экрана с помощью флага SetConsoleMode. Вы можете использовать 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[]){

    // Console handlers
    DWORD dwOldMode, dwMode ;
    HANDLE hStdout;

    // Pipe read buffer
    int c;

    // Spawn process variables
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    // Retrieve standard output handle
    hStdout = GetStdHandle( STD_OUTPUT_HANDLE );
    if (! GetConsoleMode( hStdout, &dwOldMode ) ) {
        return 1;
    }

    // Change standard output handle
    dwMode = dwOldMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    if (! SetConsoleMode( hStdout, dwMode ) ){
        CloseHandle( hStdout );
        return 2;
    }

    if( argc < 2 ) {
        // If there is not an argument, read stdin / write stdout 
        while ( EOF != (c = getchar()) ) putchar( c );    
    } else {
        // Argument is present, create a process and wait for it to end
        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 );    
    }

    // Restore old console mode
    SetConsoleMode( hStdout, dwOldMode );
    CloseHandle( hStdout );

    return 0;
};

составлен в run.exe С mingw/gcc. Результаты

Output capture of test session

теперь, выход из cscript и findstr обрабатывается и интерпретируются escape-последовательности.

кроме того, если вместо запуска отдельных программ я запускаю cmd.exe сам

Output capture of redirected cmd.exe

так как я не менял код findstr.exe, cscript.exe или cmd.exe, только окружающая среда, где они работают это кажется это

  • ни cscript, ни findstr настройка / изменение конфигурации буфера консоли

  • внутренние cmd команды изменяют конфигурацию буфера (я забыл включить его в захват, но copy test.txt con и prompt тоже работа) или, как вы указываете, они используют другой метод вывода

  • единственное требование для приложения, которое записывает в стандартный выходной поток, - это правильная настройка режима буфера вывода консоли.

и нет, я не знаю как включить его из чистого пакета.


хорошо, я думаю, что у меня есть жизнеспособная теория о том, почему она не работает. Я считаю, что должен быть какой-то низкоуровневый способ/вызов/функция/метод (что угодно) для передачи stdout на консоль, о которой знают только несколько внутренних команд. Я основываю это на том, что FINDSTR также не может отправлять функционирующие escape-последовательности на консоль, как показано ниже:

enter image description here

Я уже показал, что оба типа и Эхо работают. Я также проверил, что SET / P работает (не показан.) Поэтому я подозреваю, что cmd.exe был изменен для поддержки новых функций консоли Windows 10.

Я хотел бы увидеть некоторую документацию MS, описывающую необходимый механизм отправки escape-последовательностей на консоль.