web-dev-qa-db-ja.com

Windows 10コンソールでANSIエスケープシーケンスの新しいサポートを使用するにはどうすればよいですか?

最新のWindows10アップデートには、conhost.exeに ANSIエスケープシーケンスのサポート が含まれています。

enter image description here

エスケープシーケンスがcmd.exeで正しく取得されていることを確認できたので、必要な更新を行います。特に、カーソルを非表示にするPrompt $e[?25lを入力してから、再びカーソルを表示するPrompt $e[?25hを入力してみました。

ただし、Pythonインタープリターを起動してから、次のようにします。

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

まあ、カーソルは隠されていません。コンソールがPythonからエスケープシーケンスを取得できるように、正しい方法で設定するにはどうすればよいですか?

18
user89

問題は、PythonインタープリターがANSIエスケープシーケンスの処理を有効にしないことです。ANSIシーケンスは、cmdが有効にするため、Windowsコマンドプロンプトから機能します。開始した場合Pythonコマンドプロンプトから、カーソルの有効化と無効化を含むANSIシーケンスが機能することがわかります。これは、cmdがすでにそのコンソールウィンドウでそれらを有効にしているためです。 。

クリックしてPython ANSIエスケープを有効にしたインタープリターを起動できるものが必要な場合は、cmd /c C:\PythonXY\pythonのようなコマンドを実行するショートカットを作成できます。

もう1つの難しい解決策は、ctypesを使用して、 ENABLE_VIRTUAL_TERMINAL_PROCESSING フラグを設定してSetConsoleMode Windows APIを呼び出すことにより、コンソールウィンドウのANSIエスケープシーケンス処理を有効にすることです。例えば:

import ctypes

kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
29
Ross Ridge

私が提案したいくつかのコードのこの適応 ここ はあなたが始めるのに役立つはずです。 Windows 10ANSI VTモード(仮想端末処理)を有効にします。引数値を渡す1 forstdoutまたは2stderr

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
1
Glenn Slayden