how can I use more colors in console while using WriteConsoleOutput and WriteConsoleOutputAttribute?
I found you can write ANSI colors using Console.Write, but how can I do this using those two methods?
In C# is works like in C. I use it in C# some minutes ago and it works fine. Here is the Color table: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
C# Example:
Console.Write("\x1B[38;5;{0}m", runtime.Register[2]);
C Example:
printf ( "\x1B[38;5;%dm", color );
You have to opt-in on Windows to use ANSI color codes. It's not enabled by default.
using System.Runtime.InteropServices;
public static class ConsoleColor {
private const int STD_OUTPUT_HANDLE = -11;
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
public static void Initialize() {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
EnableAnsiEscapeSequencesOnWindows();
}
}
private static void EnableAnsiEscapeSequencesOnWindows() {
IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (handle == IntPtr.Zero) {
throw new Exception("Cannot get standard output handle");
}
if (!GetConsoleMode(handle, out uint mode)) {
throw new Exception("Cannot get console mode");
}
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(handle, mode)) {
throw new Exception("Cannot set console mode");
}
}
}
It doesn't matter that we just initialize stdout. It colors work on stderr to once virtual terminal processing is enabled.
static int Main(string[] args) {
ConsoleColor.Initialize();
const string AnsiError = "\x1b[38;5;161m";
const string AnsiReset = "\x1b[0m";
Console.Error.WriteLine(AnsiError + "One or more tests failed!" + AnsiReset);
}
You can used Ansi escape codes
to color console text as it was possible with python I tried and have created a small extension on string to format & color the console text.
But unlike other answers it is a color mixed that works with RGB(255,255,255)
and Css Hex Colors
so it's not limited to the standard set of colors
Extension: Holi.cs
//Holi.cs
public static class Holi
{
const int STD_OUTPUT_HANDLE = -11;
const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
public const string RESET = "\x1B[0m";
public const string UNDERLINE = "\x1B[4m";
public const string BOLD = "\x1B[1m";
public const string ITALIC = "\x1B[3m";
public const string BLINK = "\x1B[5m";
public const string BLINKRAPID = "\x1B[6m";
public const string DEFAULTFORE = "\x1B[39m";
public const string DEFAULTBACK = "\x1B[49m";
static Holi()
{
var handle = GetStdHandle(STD_OUTPUT_HANDLE);
uint mode;
GetConsoleMode(handle, out mode);
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(handle, mode);
}
public static byte[] HexToRgb(string hexcolor)
{
hexcolor = hexcolor.Remove(0, 1);
if (hexcolor.Length != 6)
throw new Exception("Not a valid hex color");
string[] rgb = hexcolor.Select((obj, index) => new { obj, index })
.GroupBy(o => o.index / 2)
.Select(g => new string(g.Select(a => a.obj)
.ToArray())).ToArray<string>();
return new byte[] { Convert.ToByte(rgb[0], 16), Convert.ToByte(rgb[1], 16), Convert.ToByte(rgb[2], 16) };
}
public static string ForeColor(this string text,byte red, byte green, byte blue)
{
return $"\x1B[38;2;{red};{green};{blue}m{text}";
}
public static string ForeColor(this string text, string hexrgb)
{
byte[] rgb = HexToRgb(hexrgb);
return ForeColor(text, rgb[0], rgb[1], rgb[2]);
}
public static string BackColor(this string text, byte red, byte green, byte blue)
{
return $"\x1B[48;2;{red};{green};{blue}m{text}";
}
public static string BackColor(this string text, string hexrgb)
{
byte[] rgb = HexToRgb(hexrgb);
return BackColor(text, rgb[0], rgb[1], rgb[2]);
}
public static string ResetColor(this string text)
{
return $"{RESET}{text}";
}
public static string Bold(this string text)
{
return $"{BOLD}{text}";
}
public static string Italic(this string text)
{
return $"{ITALIC}{text}";
}
public static string Underline(this string text)
{
return $"{UNDERLINE}{text}";
}
public static string Add(this string text,string addText)
{
return $"{text}{RESET}{addText}";
}
public static void Print(this string text,string prefix=null)
{
Console.WriteLine($"{prefix}{text}{RESET}");
}
public static void Printf(this string text, byte red=0, byte green=0, byte blue = 0)
{
Console.Write($"{ForeColor(red,green,blue)}{text}{RESET}");
}
public static void Printf(this string text, string hexColor)
{
byte[] rgb = HexToRgb(hexColor);
Console.Write($"{ForeColor(rgb[0], rgb[1], rgb[2])}{text}{RESET}");
}
public static string ForeColor(params byte[] rgb)
{
if (rgb == null || rgb.Length == 0)
return "\x1B[0m";
if (rgb.Length == 3)
return $"\x1B[38;2;{rgb[0]};{rgb[1]};{rgb[2]}m";
if (rgb.Length == 2)
return $"\x1B[38;2;{rgb[0]};{rgb[1]};0m";
if (rgb.Length == 2)
return $"\x1B[38;2;{rgb[0]};0;0m";
return "\x1B[0m";
}
public static string BackColor(params byte[] rgb)
{
if (rgb == null || rgb.Length == 0)
return "\x1B[0m";
if (rgb.Length == 3)
return $"\x1B[48;2;{rgb[0]};{rgb[1]};{rgb[2]}m";
if (rgb.Length == 2)
return $"\x1B[48;2;{rgb[0]};{rgb[1]};0m";
if (rgb.Length == 2)
return $"\x1B[48;2;{rgb[0]};0;0m";
return "\x1B[0m";
}
}
Example
Which can be used as:
//printf
"Printf Example\n".Printf(200, 255, 0);
//print
"#FFAAEE\n".ForeColor("#C8FF00").Print();
//format + print
"\n RGB colored text".ForeColor(255,200,0).Print();
"\n HEX colored text".ForeColor("#FFC800").Print();
"\n RGB back colored text".BackColor(50, 0, 0).ResetColor().Add(" no background color ").Print();
"\n HEX back colored text".BackColor("#320000").Print();
"\n Bold Text".Bold().Print();
"\n Underline text".Underline().Add(" no underline ").Print();
//writline
var c = ForeColor(200, 255, 0);
Console.WriteLine($"Same {c}" + UNDERLINE + "underlined green" + RESET + " text");
Output
To get the following output in Microsoft Windows [Version 10.0.19044.2728]
© 2022 - 2024 — McMap. All rights reserved.
Console.ForegroundColor = ConsoleColor.Red
for example red. Then reset with `Console. ResetColor()' ... if that is what you were looking to do. – Belmonte