62

让控制台支持 ANSI 转义序列,输出下划线、修改颜色或其他控制

 5 years ago
source link: https://walterlv.github.io/post/enable-virtual-terminal-processing.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

各种操作系统的控制台都支持 ANSI 转义序列(ANSI Escape Code)。使用转义序列,可以对控制台进行很多额外的定制,例如修改颜色、修改标题栏,将文字添加下划线等。

当然,.NET 已经帮助我们封装了很大的一部分功能了,我们重点可以放在 .NET 没有封装的那部分上。

基本的准备代码

在开始之前,我们先添加一些基础性代码,这是对系统核心功能的调用。

const int STD_OUTPUT_HANDLE = -11;
const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;

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

在 Main 函数中,添加一些调用:

static void Main(string[] args)
{
    Console.Title = "Walterlv.Demo";

    var handle = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleMode(handle, out var mode);
    mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(handle, mode);

    // 我们准备在这里添加新的代码。
    
    Console.Read();
}

开始使用 ANSI 转义序列

添加下划线

const string UNDERLINE = "\x1B[4m";
const string RESET = "\x1B[0m";
Console.WriteLine($"Some {UNDERLINE}underlined{RESET} text");

buEbiqq.png!web ▲ 下划线转义

修改颜色

const string RED = "\x1B[31m";
Console.WriteLine($"Some {UNDERLINE}underlined{RESET} and {RED}red{RESET} text");

BBJnEz6.png!web ▲ 颜色转义(当然,.NET 封装有 API)

其他转义序列

其他转义序列,可阅读 ANSI escape code - Wikipedia 。不过 Windows 能支持的并不多。

关于颜色,不同控制台上对于相同转义序列的颜色值和颜色支持程度也不同。

关于 ENABLE_VIRTUAL_TERMINAL_PROCESSING

这是用来开启虚拟终端处理的一个标识,Windows 从一开始就默认关闭这个标识,必须通过 SetConsoleMode 手工开启。虽然在 10.0.10586 版本时短暂开启了一个版本,随后在 10.0.14393 中又再次默认关闭了。

参考资料

本文会经常更新,请阅读原文: https://walterlv.github.io/post/enable-virtual-terminal-processing.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

VrIr6j.png!web 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK