Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
822 views
in Technique[技术] by (71.8m points)

batch file - How to use ANSI escape sequences with CSCRIPT on Windows 10?

I'm trying to use the new VT100 ANSI escape sequence capabilities available in the Windows 10 console with CSCRIPT (JScript). But I cannot get it to work.

Here is a really simple JScript script:

test.js

WScript.Echo('x1B[7mReversex1B[0m Normal');
WScript.stdout.WriteLine('x1B[7mReversex1B[0m Normal');

I've done a number of tests, and the escape sequences output by CSCRIPT are impotent when written directly to the screen, and only work if written to a file first and then TYPEed, or else captured by FOR /F and ECHOed.

enter image description here

I have two questions:

1) Why doesn't the direct write to the console work from CSCRIPT?
2) How can I get the direct write to work?

I would like to add text highlighting to my JREPL.BAT regular expression find/replace utility (hence the tag), but I will not implement that feature if it requires a temporary file and/or FOR /F.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

MS documentation states

The following terminal sequences are intercepted by the console host when written into the output stream if the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is set on the screen buffer handle using the SetConsoleMode flag. You can use GetConsoleMode and SetConsoleMode flags to configure this behavior.

So, just to test, I wrote a simple C program to change the console mode and then act as a pipe or launch another process and wait (sorry, just test code).

#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).
", GetLastError() );
            return 3;
        }
        WaitForSingleObject( pi.hProcess, INFINITE );
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );    
    }

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

    return 0;
};

Compiled to run.exe with mingw/gcc. The results are

Output capture of test session

Now, the output from cscript and findstr is processed and the escape sequences are interpreted.

Also, if instead of running the separate programs, I run cmd.exe itself

Output capture of redirected cmd.exe

Since I have not changed the code from findstr.exe, cscript.exe or cmd.exe, only the environment where they are working it seems that

  • neither cscript nor findstr configure/change the console buffer configuration

  • some internal cmd commands change the buffer configuration (I forget to include it in the capture, but copy test.txt con and prompt also work) or, as you point, they use a different output method

  • the only requirement for an application that writes to the standard output stream is that the console output buffer mode is properly configured.

And no, I don't know how to enable it from pure batch.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...