首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ANSI / VT100代码在PowerShell控制台中输出彩色文本

使用ANSI / VT100代码在PowerShell控制台中输出彩色文本
EN

Stack Overflow用户
提问于 2018-08-04 06:19:35
回答 3查看 18.8K关注 0票数 35

我写了一个程序,它打印一个字符串,其中包含ANSI escape sequences以使文本着色。但它在默认的Windows10控制台上并不能像你在屏幕截图中看到的那样工作。

程序输出以打印字符的形式显示转义序列。如果我通过变量或管道将该字符串提供给PowerShell,则输出将按预期显示(红色文本)。

我如何才能实现程序打印彩色文本而不使用任何变通方法?

这是我的程序源代码(Haskell) --但是语言并不重要,只是为了让你看看转义序列是如何编写的。

代码语言:javascript
复制
main = do
    let red = "\ESC[31m"
    let reset = "\ESC[39m"
    putStrLn $ red ++ "RED" ++ reset
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-04 09:20:53

虽然Windows10中的控制台窗口原则上支持VT (虚拟终端)/ ANSI转义序列,但支持在默认情况下关闭了

您有三个选项:

this SU answer.中所述,

  • (a) Activate support 默认为全局激活,通过注册表永久激活

代码语言:javascript
复制
- In short: In registry key `[HKEY_CURRENT_USER\Console]`, create or set the `VirtualTerminalLevel` DWORD value to `1` 
    - From PowerShell, you can do this _programmatically_ as follows:

Set-ItemProperty HKCU:\Console VirtualTerminalLevel -Type DWORD 1

-来自cmd.exe (也适用于PowerShell):

reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1

代码语言:javascript
复制
- Open a new console window for changes to take effect.
- See caveats below.

  • (b) Activate通过调用SetConsoleMode() Windows API函数从程序内部支持,仅适用于程序(进程)。

代码语言:javascript
复制
- See details below.

  • (c) 临时解决方法,来自PowerShell的 :通过管道将外部程序的输出传送到Out-Host;例如,.\test.exe | Out-Host

代码语言:javascript
复制
- See details below.

回复(a):

基于注册表的方法总是激活globally,的VT支持,即 console ,无论在其中运行什么外壳/程序:

如果需要,

  • 单个可执行文件/ shells仍可以使用方法(B)停用对其自身的支持。

  • 相反,这意味着没有显式控制VT支持的任何程序的输出都将受到VT序列的解释;虽然这通常是可取的,但假设这可能导致对意外产生类似VT序列的输出的程序的输出的误解。

注意:

  • 虽然有一种机制允许通过启动可执行文件/窗口标题通过[HKEY_CURRENT_USR\Console]的子键来限定控制台窗口设置的范围,但VirtualTerminalLevel值似乎不受支持。

  • 即使是,它也不是一个健壮的解决方案,因为通过快捷文件(*.lnk) (例如,从开始菜单或任务栏)打开控制台窗口不会遵守这些设置,因为*.lnk文件具有内置设置;虽然您可以通过Properties图形用户界面对话框修改这些内置设置,但在撰写本文时,VirtualTerminalLevel设置还没有出现在该图形用户界面中。

回复(b):

从程序(进程)内部调用SetConsoleMode() Windows API函数(如here所述)即使在C#中也很麻烦(因为需要P/Invoke声明),并且可能不是选项

对于使用不支持调用Windows API的语言编写的程序,请使用

如果您具有无法修改的预先存在的可执行文件,请执行

如果您不想在这种情况下启用全局支持(选项(a)),选项(c) (来自PowerShell)可能对您有效。

回复(c):

PowerShell在启动时自动激活VT (虚拟终端)支持本身(在最新版本的Windows10中,这适用于Windows PowerShell和PowerShell核心)-但不会将扩展到外部程序E294 E294 E195从E197调用。

但是,if you an external program's output via PowerShell,VT sequences are Out-Host是最简单的方法(Write-Host也可以):

代码语言:javascript
复制
.\t.exe | Out-Host

注意:仅当您打算打印到控制台时才使用Out-Host;相反,如果您希望捕获外部程序的输出,则仅使用$capturedOutput = .\test.exe

原始设备制造商字符编码警告:默认情况下,Windows PowerShell期望外部程序的输出使用代码页,该代码页由旧版系统区域设置(例如,美英系统上的437 )定义,并反映在[console]::OutputEncoding中。.NET控制台程序自动遵循该设置,但对于使用不同编码的非.NET程序(例如,Python脚本)(并且不仅产生纯ASCII码输出(在7位范围内)),您必须(至少临时地)通过将该编码赋值给[console]::OutputEncoding来指定该编码;例如,对于UTF8:

[console]::OutputEncoding = [Text.Encoding]::Utf8

请注意,这不仅是VT序列解决方法所必需的,而且通常也是PowerShell正确解释非字符所必需的。

不幸的是,在7.2版本中,OEM (v6+)仍然默认使用PowerShell代码页,但如果不使用should be considered a ,它将默认使用UTF8。

票数 81
EN

Stack Overflow用户

发布于 2018-08-04 16:21:43

感谢用户mklement0让我意识到VT支持不是自动启用的。这让我找到了正确的方向,我找到了this helpful post

所以回答我的问题:添加或设置注册表项

代码语言:javascript
复制
HKCU:\Console  -  [DWORD] VirtualTerminalLevel = 1

重启控制台即可正常工作。

票数 14
EN

Stack Overflow用户

发布于 2021-04-16 19:37:32

特别是对于Haskell,您需要在Windows10上的程序中调用hSupportsANSIWithoutEmulation函数来启用ANSI转义序列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51680709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档