2015-12-03 3 views
4

Я пытаюсь генерировать цветной консольный вывод с помощью ANSI escape codes со следующей минимальной C# программы:ANSI-раскраска консоль Вывод с .NET

using System; 

// test.cs 
class foo { 
    static void Main(string[] args) { 
     Console.WriteLine("\x1b[36mTEST\x1b[0m"); 
    } 
} 

Я бег Ansicon v1.66 ​​на Windows 7 x64 с csc.exe (Microsoft (R) Visual C# компилятор версии 4.6.0081.0).

Цветной выход прекрасно работает в этой конфигурации; Ansicon сам работает безупречно.

Для перепроверки я использую Node.js Однострочник, который 100% эквивалентно C# программы:

// test.js 
console.log("\x1b[36mTEST\x1b[0m"); 

И, еще более простой, ручной созданный текстовый файл:

text file hex editor screenshot

Оба из которых, правильно сделать ожидаемую вещь: Печать чирка -colored строки "TEST":

enter image description here

Только файл test.exe, который я построил с помощью csc, печатает что-то еще. Зачем?

+0

его не очень правильный код побега в C#, см: https: // MSDN. microsoft.com/en-us/library/h21280bw.aspx Похоже, что строка '\ x1b' превращается в непечатаемый символ перед выходом на консоль, а остальная часть выводится как-есть. Если вы хотите попробовать выводить необработанный текст, добавьте строку с символом '@', aka: 'Console.WriteLine (@" \ x1b [36mTEST \ x1b [0m ");' –

+0

@RonBeyer Проведенный это действительный escape-код. Это символ ASCII ESC. – Tomalak

+0

@Tomalak Как вы ожидаете печати символа ESC? –

ответ

3

Ваша программа должна быть скомпилирована для /platform:x64, если вы используете среду AnsiCon x64 и с /platform:x86, если используете версию AnsiCon x86/32 bit. Точная причина есть тайна ...

Первоначально я думал, что ты все это нужно:

Вы должны захватить StandardOutput и пусть Console.WriteLine считают, вы пишете в файл, а не к консоли и использовать кодировку ASCII.

Вот как это будет работать:

var stdout = Console.OpenStandardOutput(); 
var con = new StreamWriter(stdout, Encoding.ASCII); 
con.AutoFlush = true; 
Console.SetOut(con); 

Console.WriteLine("\x1b[36mTEST\x1b[0m"); 

В .NET Console.WriteLine использует внутренний __ConsoleStream, который проверяет, если Console.Out как дескриптор файла или консольную ручку. По умолчанию он использует консольный дескриптор и поэтому записывает на консоль, вызывая WriteConsoleW. В примечаниях вы найдете:

Хотя приложение может использовать WriteConsole в режиме ANSI для написания символов ANSI, консоли не поддерживают escape-последовательности ANSI. Однако некоторые функции обеспечивают эквивалентную функциональность. Для получения дополнительной информации см. SetCursorPos, SetConsoleTextAttribute и GetConsoleCursorInfo.

Чтобы записать байты непосредственно в консоль без WriteConsoleW мешая простой/поток ссылку на файл будет делать что достигается путем вызова OpenStandardOutput. Упакуя этот поток в StreamWriter, чтобы мы могли его снова установить с Console.SetOut, мы закончили. Последовательности байтов отправляются в OutputStream и выбираются AnsiCon.

ли уведомление, что это полезное только применимым эмулятор терминала, как AnsiCon, как показано здесь:

enter image description here

+0

Это потрясающе, спасибо вам большое. – Tomalak

+0

... К сожалению, он не работает. После изменения выход вашей программы остается тем же самым [36m ... TEST ... [0m' для меня (плюс видимые символы замены для '\ x1b'). – Tomalak

+0

@ Томалак хм, может быть, он имеет какое-то отношение к кодировке по умолчанию. В моем эксперименте прошлой ночью я впервые пошел по маршруту, чтобы получить ASCII-кодированный байтовый массив тестовой строки, а затем сделать Console.OpenStandardOutput(). WriteByte (array, 0, array.Length); Когда это сработало, я переработал материал в своем рабочем примере. Может, потоковому потоку нужна кодировка? – rene

Смежные вопросы