2

Is there a way to make windows output ansi escape sequences after internal console color changes? I know about things like ansicon that will INTERPRET ansi escape sequences output by a program being ran, but I am wondering if there is a way that windows will forward those escape sequences through stdout. For example


#include 
#include 
using namespace std;
HANDLE hCon;

enum Color { DARKBLUE = 1, DARKGREEN, DARKTEAL, DARKRED, DARKPINK, DARKYELLOW, GRAY, DARKGRAY, BLUE, GREEN, TEAL, RED, PINK, YELLOW, WHITE };

void SetColor(Color c){
        if(hCon == NULL)
                hCon = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(hCon, c);
}

int main()
{
    std::cout "\x1b[31;1m  I should be red if printed on the console, otherwise I should have passed that ansi code to stdout.\n";
    SetColor(GREEN);
    cout "I should be green if printed on the console, but I should have passed the escape sequence to the stdout pipe..\n";
    char x;
    std::cin.get(x);
}

I want the byte level data being sent on stdout to be in ALL ansi approved text including color codes and cursor movement escaped sequences.. I'm not even sure that's possible but if any one knew... HERE would be the place to know if it's already been done. I am also open to possibilities on rolling my own and adding it to ansicon.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
Rusty Weber
  • 1,541
  • 1
  • 19
  • 32
  • 1
    @Hans Passant: I don't think this question is a duplicate of the question you marked this as duplicate of. Although similar, there are some key defining aspects. The question you linked to is how to program your program to output ascii.. I was looking for a way to have an already compiled program give me ansii codes. – Rusty Weber May 21 '14 at 03:10
  • @Hans Passant: This question is not a duplicate; it is trying to solve the opposite direction of the problem you've linked. – user314104 May 21 '14 at 16:22

3 Answers3

1

An approach that I've seen in the open-source KpyM Telnet/SSH Server was the use of GetConsoleScreenBufferInfo and ReadConsoleOutput.

Rather than manipulating the console I/O routines to emit terminal escape sequences, KTS creates a new console window and captures data from it through the handles it owns and the GetConsoleScreenBufferInfo (cursor information) and ReadConsoleOutput (on-screen information, including colors) functions. After capturing the data, KTS emits the appropriate terminal escape sequences to the remote end to reproduce the display.

This behavior requires no hooks beyond what's provided in the Win32 API and works well for interactive applications, but it can result in screen "tearing", especially when a large amount of output is dumped to the console and the SSH daemon isn't polling fast enough to keep up. Additionally, because this mechanism uses polling, it will consume more power, especially on mobile devices acting as a server, and on mobile clients with a naive server implementation. (An intelligent server implementation could detect that nothing has changed, reducing the data sent to a mobile client.)

If you are planning on implementing (or have already implemented) an SSH daemon for Windows, don't forget that not all applications will want this terminal emulation behavior -- only when you get a pty-req message should this terminal emulation be done. If you don't receive a pty-req message, the SSH daemon should merely relay the standard input/standard output/standard error streams.

user314104
  • 1,528
  • 14
  • 31
0

I am pretty sure that there is nothing that ships with any Windows OS since Windows 2000 that includes support for ANSI Escape sequences.

It also makes sense, if you consider the limitations of ANSI http://www.roysac.com/learn/ansisys.html, just 16 colors (that are fix), only 8 of them usable as background color etc.

Unless you need to be backwards compatible that far into the past or for nostalgic reasons (that last category would include myself actually :)), there is no reason to go with ANSI Escape Sequences.

If you look at the documentation (link), you will also learn that the old ANSI stuff isn't very intuitive and easy to use and certainly not straight forward also. The old PCBoard ANSI equivalent encoding @X00 .. @X7F (@X instead of CHR(27) "ESC" then 1 byte BackColor (Hex) and 1 byte ForeColor (Hex) was a walk in a park in comparison :)

  • 1
    The whole reason that this came about is that I was hoping to open source an ssh server for windows that doesn't run an augmented environment.. **cough cough CYGWIN cough**, Something that would be as close to running cmd on a windows machine through ssh as possible. AFIK, ssh uses the ascii codes for color as well as cursor placement. So, I guess the real question would be, is there a good porting layer of some kind that can port .cmd into something an ssh channel can use. – Rusty Weber May 21 '14 at 03:04
  • PS. the paid version of what I am talking about is Bitvise if you would like a reference. – Rusty Weber May 21 '14 at 03:05
  • I don't believe the SSH protocol mandates ANSI escape sequences for color / cursor placement. The notions of color/cursor placement is up to the application that's running in SSH; often, that application makes assumptions for escape sequences through `ncurses`/`termios`. On the Windows NT family, applications use the console APIs instead of `ncurses`/`termios`. The furthest that SSH reaches into that, as far as I know, is through the `pty-req` and `window-change` message types. – user314104 May 21 '14 at 16:19
  • Let's assume that you are correct, as you very may well be. this still leaves the problem of how to detect those lower level calls so that the appropriate action can be taken even though that action no longer involves using ansi color codes and the like. – Rusty Weber May 24 '14 at 04:13
  • See the two other answers I've provided. The answer in http://stackoverflow.com/a/23915607/314104 has been done before in KTS, and it does, indeed, work, although it isn't very clean. The answer in http://stackoverflow.com/a/23788965/314104 is probably cleaner; if you can't use Detours, consider the strategy mentioned in http://stackoverflow.com/a/4975615/314104. – user314104 May 28 '14 at 15:33
0

While this is a bit of a kludge, you might be able to solve it through the use of Detours and emitting the appropriate ANSI escape sequences. On calls to the console API functions, you'd emit the appropriate escape sequences to the standard output stream.

(I hope someone suggests a better answer, because, while this should work, it's a horrible hack.)

user314104
  • 1,528
  • 14
  • 31