Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansi colours on Windows 10, sort of not working

Console with colours is fairly new and exciting for Windows :-)

I wrote some programs that printed using the ansi colour escapes and all was good ...

... then suddenly it stopped working. Or at least stopped on my laptop, Windows 10.0.14393

The app that fails on my machine does so in a console that a nodejs app has displayed colour in, the same binary runs with the correct colour on another laptop.

golang fmt.Println("\033[31mSome Text\033[0m")

It looks like this

left-top, console node output, left-bottom, my app failing, right vscode

httpDump.exe is the name of this demo (in case it was confusing)

It does display correctly in the vscode integrated terminal window.

I've tried deleting the HKLM\Console registry entry and restarting (several times). I deleted the short-cut that may have settings in it. I've tried running as another user on this machine (does not work)

I'd welcome any hints.

like image 251
Adam Straughan Avatar asked Sep 21 '16 22:09

Adam Straughan


2 Answers

You have to enable virtual terminal processing on Windows since that update.

I usually add a file init_windows.go which sets this in windows but is also compatible with other OS:

// +build windows

package main

import (
    "os"

    "golang.org/x/sys/windows"
)

func init() {
    stdout := windows.Handle(os.Stdout.Fd())
    var originalMode uint32

    windows.GetConsoleMode(stdout, &originalMode)
    windows.SetConsoleMode(stdout, originalMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
}

as copied from: https://github.com/sirupsen/logrus/issues/172#issuecomment-353724264

like image 108
sieberts Avatar answered Sep 20 '22 13:09

sieberts


You can enable virtual terminal processing using just standard library packages:

In init_windows.go

//go:build windows

package main

import (
    "os"
    "syscall"
)

func init() {
    stdout := syscall.Handle(os.Stdout.Fd())

    var originalMode uint32
    syscall.GetConsoleMode(stdout, &originalMode)
    originalMode |= 0x0004
    
    syscall.MustLoadDLL("kernel32").MustFindProc("SetConsoleMode").Call(uintptr(stdout), uintptr(originalMode))
}
like image 37
I.Am.A.Guy Avatar answered Sep 18 '22 13:09

I.Am.A.Guy