如何在Windows 10控制台中使用ANSI转义序列的新支持?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Windows 10控制台中使用ANSI转义序列的新支持?相关的知识,希望对你有一定的参考价值。

最新的Windows 10更新包括conhost.exe中的support for ANSI escape sequences

enter image description here

我已经能够确认在cmd.exe中正确地获取了转义序列,所以我有必要的更新。特别是,我尝试键入prompt $e[?25l,它隐藏光标,然后prompt $e[?25h,它再次显示光标。

但是,如果我启动Python解释器,然后执行以下操作:

>>> import sys
>>> sys.stdout.write("33[?25l")

好吧,光标没有隐藏。如何以正确的方式设置,以便控制台能够从Python获取转义序列?

答案

问题是Python解释器不能处理ANSI转义序列。 ANSI序列在Windows命令提示符下工作,因为cmd确实启用了它们。如果从命令提示符启动Python,您将发现ANSI序列确实有效,包括用于启用和禁用游标的序列。那是因为cmd已经为那个控制台窗口启用了它们。

如果你想要点击某些内容来启动启用ANSI转义的Python解释器,你可以创建一个运行命令的快捷方式,如cmd /c C:PythonXYpython

另一个更难的解决方案是使用ctypes为控制台窗口启用ANSI转义序列处理,方法是调用带有SetConsoleMode标志的ENABLE_VIRTUAL_TERMINAL_PROCESSING Windows API。例如:

import ctypes

kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
另一答案

我对here提出的一些代码的改编应该有助于你开始。在Windows 10上启用ANSI VT模式(虚拟终端处理)。为stdout或1 stderr传入参数值2

def _windows_enable_ANSI(std_id):
    """Enable Windows 10 cmd.exe ANSI VT Virtual Terminal Processing."""
    from ctypes import byref, POINTER, windll, WINFUNCTYPE
    from ctypes.wintypes import BOOL, DWORD, HANDLE

    GetStdHandle = compat_ctypes_WINFUNCTYPE(
        HANDLE,
        DWORD)(('GetStdHandle', windll.kernel32))

    GetFileType = compat_ctypes_WINFUNCTYPE(
        DWORD,
        HANDLE)(('GetFileType', windll.kernel32))

    GetConsoleMode = compat_ctypes_WINFUNCTYPE(
        BOOL,
        HANDLE,
        POINTER(DWORD))(('GetConsoleMode', windll.kernel32))

    SetConsoleMode = compat_ctypes_WINFUNCTYPE(
        BOOL,
        HANDLE,
        DWORD)(('SetConsoleMode', windll.kernel32))

    if std_id == 1:       # stdout
        h = GetStdHandle(-11)
    elif std_id == 2:     # stderr
        h = GetStdHandle(-12)
    else:
        return False

    if h is None or h == HANDLE(-1):
        return False

    FILE_TYPE_CHAR = 0x0002
    if (GetFileType(h) & 3) != FILE_TYPE_CHAR:
        return False

    mode = DWORD()
    if not GetConsoleMode(h, byref(mode)):
        return False

    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
    if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0:
        SetConsoleMode(h, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
    return True

以上是关于如何在Windows 10控制台中使用ANSI转义序列的新支持?的主要内容,如果未能解决你的问题,请参考以下文章

Python:如何使 ANSI 转义码在 Windows 中也能正常工作?

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

如何让 win32 控制台识别 ANSI/VT100 转义序列?

如何使用 ANSI Escape 代码在控制台上输出彩色文本

[C#, 笔记] 启用虚拟终端处理 (使用 ANSI 转义序列前需启用)

[C#, 笔记] 启用虚拟终端处理 (使用 ANSI 转义序列前需启用)