ANSI 颜色并直接写入控制台输出 C#

问题描述 投票:0回答:3

如何在使用 WriteConsoleOutput 和 WriteConsoleOutputAttribute 时在控制台中使用更多颜色?
我发现您可以使用 Console.Write 编写 ANSI 颜色,但是我如何使用这两种方法来完成此操作?

c# .net console console-application ansi-colors
3个回答
1
投票

在 C# 中就像在 C 中一样工作。几分钟前我在 C# 中使用它并且工作正常。 这是颜色表:https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit

C# 例子:

    Console.Write("\x1B[38;5;{0}m", runtime.Register[2]);

C 例子:

    printf ( "\x1B[38;5;%dm", color );

0
投票

您必须在 Windows 上选择加入才能使用 ANSI 颜色代码。默认情况下未启用。

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");
    }
  }
}

我们只是初始化stdout没关系。一旦启用虚拟终端处理,它就会在 stderr 上工作。

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);
}

0
投票

您可以使用

Ansi escape codes
为控制台文本着色,就像python一样我尝试并创建了一个小的字符串扩展来格式化和着色控制台文本。

但与其他答案不同的是,它是一种混合颜色,适用于

RGB(255,255,255)
Css Hex Colors
所以它不限于标准颜色集

扩展名: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";
    }

}

例子

可以用作:

//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");

输出

Microsoft Windows [版本 10.0.19044.2728] 中获得以下输出

© www.soinside.com 2019 - 2024. All rights reserved.