programing

ANSI/VT100 코드를 사용한 PowerShell 콘솔의 컬러 텍스트 출력

batch 2023. 7. 25. 20:47
반응형

ANSI/VT100 코드를 사용한 PowerShell 콘솔의 컬러 텍스트 출력

저는 문자열을 출력하는 프로그램을 썼는데, 텍스트를 색칠하기 위해 ANSI 이스케이프 시퀀스가 포함되어 있습니다.그러나 스크린샷에서 볼 수 있듯이 기본 Windows 10 콘솔에서는 예상대로 작동하지 않습니다.

프로그램 출력이 이스케이프 시퀀스와 함께 인쇄된 문자로 나타납니다.변수 또는 파이프를 통해 해당 문자열을 PowerShell에 공급하면 출력이 의도한 대로 표시됩니다(빨간색 텍스트).

해결 방법 없이 프로그램에서 컬러 텍스트를 인쇄하려면 어떻게 해야 합니까?

enter image description here

이것은 나의 프로그램 소스(해스켈)입니다. 하지만 언어는 관련이 없습니다. 단지 탈출 시퀀스가 어떻게 작성되는지 볼 수 있습니다.

main = do
    let red = "\ESC[31m"
    let reset = "\ESC[39m"
    putStrLn $ red ++ "RED" ++ reset

참고:

  • 다음은 Windows(윈도우)의 일반 콘솔 창에 적용됩니다(가 제공).conhost.exe콘솔 응용 프로그램이 GUI 응용 프로그램에서 시작되는 경우를 포함하여 기본적으로 사용됩니다.

  • 이와 대조적으로 Windows Terminal 및 Visual Studio Code의 통합 터미널에서 제공하는 콘솔 창(터미널)은 모든 콘솔 응용 프로그램에 대해 기본적으로 VT/ANSI 이스케이프 시퀀스지원합니다.


Windows 10의 콘솔 창은 원칙적으로 VT(가상 터미널)/ANSI 이스케이프 시퀀스지원하지만 지원기본적으로 해제되어 있습니다.

세 가지 옵션이 있습니다.

  • SU 답변에 자세히 설명된 대로 레지스트리를 통해 지원을 기본적으로 전체적으로 영구적으로 활성화합니다.

    • 키에서: 스트리키내요약레지내.[HKEY_CURRENT_USER\Console]생또는을 합니다.VirtualTerminalLevel에서 DWORD »:1
      • PowerShell에서 다음과 같이 프로그래밍 방식으로 이 작업을 수행할 수 있습니다.
        Set-ItemProperty HKCU:\Console VirtualTerminalLevel -Type DWORD 1
      • cmd.exe(PowerShell 기능):
        reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1
    • 변경 내용을 적용하려면 새 콘솔 창을 엽니다.
    • 아래의 주의 사항을 참조하십시오.
  • 해당 프로그램(프로세스)에 대해서만 프로그램 내부에서 지원활성화합니다.SetConsoleMode()Windows API는 다음과 같습니다.

    • 자세한 내용은 아래를 참조하십시오.
  • PowerShell의 임시 해결 방법:

    • PowerShell (Core) 7+: 외부 프로그램 호출을 다음에 포함합니다.(...)(인쇄하기 전에 모든 출력을 먼저 수집하는 것이 좋습니다):

      • (.\test.exe)
    • Windows PowerShell 전용 대안 스트리밍: 외부 프로그램의 파이프 출력Write-Host

      • .\test.exe | Out-Host
    • 자세한 내용은 아래를 참조하십시오.


참조(a):

레지스트리 기반 접근 방식은 실행되는 셸/프로그램에 관계없이 VT 지원 세계적으로 활성화합니다.

  • 개별 실행 파일/쉘은 원하는 경우에도 방법(b)을 사용하여 자체적으로 지원을 비활성화할 수 있습니다.

  • 그러나 반대로, 이것은 VT 지원을 명시적으로 제어하지 않는 프로그램의 출력은 VT 시퀀스를 해석해야 한다는 것을 의미합니다. 일반적으로 이것이 바람직하지만, 이것은 VT 유사 시퀀스로 실수로 출력을 생성하는 프로그램의 출력을 잘못 해석할 수 있습니다.

참고:

  • 콘솔 창 설정을 시작 실행 파일/창 제목별로 범위를 지정할 수 있는 메커니즘이 있지만 다음의 하위 키를 통해[HKEY_CURRENT_USR\Console],VirtualTerminalLevel값이 지원되지 않는 것 같습니다.

  • 그렇다고 해도 바로 가기 파일을 통해 콘솔 창을 열기 때문에 강력한 솔루션은 아닐 것입니다.*.lnk 또는 에서) 하지 않을 수 (설정: " 시메작표시에서줄않존다지습") 때문입니다*.lnk파일에 기본 설정이 포함되어 있습니다. 파일을 통해 이러한 기본 설정을 수정할 수 있습니다.Properties대화상자는 에서 "GUI"를 사용합니다.VirtualTerminalLevel설정이 해당 GUI에서 표면화되지 않았습니다.


참조(b):

여기나와 있는 것처럼 프로그램(프로세스) 내부에서 Windows API 함수를 호출하는 것은 C#에서도 번거로우며(P/Invoke 선언이 필요하기 때문에) 옵션이 아닐있습니다.

  • Windows API 호출이 지원되지 않는 언어로 작성된 프로그램의 경우.

  • 수정할 수 없는 기존 실행 파일이 있는 경우.

그런 경우 다음에 설명하는 (PowerShell에서) 옵션(c)이 사용자에게 적합할 수 있습니다.


참조(c):

PowerShell은 시작할 때 자동으로 VT(가상 터미널) 지원활성화합니다(Windows 10의 최근 릴리스에서는 이 기능이 Windows PowerShell 및 PowerShell(Core) 7+ 모두에 적용됨). 그러나 v7.3.2 버전에서는 PowerShell에서 호출외부 프로그램으로 확장되지 않습니다.

  • 와는 별도로 v7.2+에는 기본 설정 변수가 있습니다. 이 변수는 PowerShell 명령포맷 시스템을 통해 컬러 출력을 생성하는지 여부제어합니다. 예를 들어,Get-ChildItem산출량.그러나 이 설정은 외부 프로그램의 직접 출력에는 영향을 주지 않습니다.$PSStyle.OutputRendering은 " " "입니다.Host즉, 단말기에 인쇄되는 형식화된 출력만 컬러로 표시됩니다.$PSStyle.OutputRendering = 'PlainText'컬러링을 비활성화합니다.$PSStyle.OutputRendering = 'Ansi'에서는 무조건적으로 설명합니다. 자세한 내용은 이 답변을 참조하십시오.

그러나 해결 방법으로 PowerShell의 (성공) 출력 스트림통해 외부 프로그램의 (stdout) 출력을 릴레이할있으며, 이 경우 VT 시퀀스인식됩니다.

  • PowerShell(Core) 7.3.2에서 이 기능은 통화를 동봉하거나 를 사용하여 작동하지만 모든 출력은 인쇄하기 [1]에 반드시 먼저 수집됩니다.

    (.\test.exe)
    
  • Windows PowerShell에서는 위의 기능 외에도 다음과 같은 기능을 통해 릴레이된 출력을 스트리밍할 수 있습니다.Write-Host(Out-Host,Write-Output또는Out-String -Stream역시 효과가 있을 것입니다.)

    .\test.exe | Write-Host
    
  • 참고: 이러한 기술은 콘솔에 인쇄하려는 경우에만 필요합니다.반대로 외부 프로그램의 출력(탈출 시퀀스 포함)을 캡처하려면 다음을 사용합니다.$capturedOutput = .\test.exe

문자 인코딩 주의:Windows PowerShell은 기본적으로 외부 프로그램의 출력이 레거시 시스템 로케일(예:437(에서), ( 시스템에서)에 된 바와 [console]::OutputEncoding은 자동으로 않은 에는 .NET 콘솔 프로그램은 이 설정을 자동으로 존중하지만 그렇지 않습니다.인코딩을 프로그램 스크립트 출력 범위하는 것이 ), [console]::OutputEncoding경우: UTF-8의 경우:
[console]::OutputEncoding = [Text.Encoding]::Utf8.
이는 VT 시퀀스 문제 해결을 위해 필요할 만 아니라 일반적으로 PowerShell이 ASC가 아닌 항목을 해석하는 데 필요합니다.II 문자가 정확합니다.

안타깝게도 PowerShell Core(v6+)는 v7.3.2에서 여전히 OEM 코드 페이지로 기본 설정되지만 그렇지 않으면 BOM 없이 UTF-8로 기본 설정되므로 버그로 간주해야 합니다(GitHub 문제 #7233 참조).


사용Out-String -Stream기능인 또는내장포기능지장된,,oss스트리밍 출력을 달성하기 위해 매력적이지만, GitHub PR #16612에서 구현된 최적화 때문에 PowerShell 7.3.2에서 더 이상 작동하지 않습니다.

VT 지원이 자동으로 활성화되지 않음을 알려준 사용자 mklement0에게 감사드립니다.이것은 저를 올바른 방향으로 바라보게 했고 저는 이 도움이 되는 게시물을 발견했습니다.

제 질문에 대답하자면:레지스트리 키 추가 또는 설정

HKCU:\Console  -  [DWORD] VirtualTerminalLevel = 1

콘솔을 다시 시작하면 작동합니다.

특히 Haskell의 경우 hSupports에 문의해야 합니다.Windows 10의 프로그램에서 ANSI 이스케이프 시퀀스를 활성화하는 ANSI(에뮬레이션 없음) 기능.

만약 누군가가 이것을 우연히 발견했지만, 그것이 작동하지 않는다면, 이것이 도움이 되기를 바랍니다.

콘솔 모드를 다음으로 변경하는 기본적인 방법을 수행하고 있습니다.ENABLE_VIRTUAL_TERMINAL_PROCESSING(0x0004저한테는 안 통했어요.

나는 파이썬과 라인과 관련된 답을 찾았습니다.

kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)

제 주의를 끌었습니다.분명히 당신이 넣으면,74ENABLE_VIRTUAL_TERMINAL_PROCESSING 시퀀스를 할 수 .), ANSI는 다음과 같습니다.

이 단말기가 어느 단말기에서 작동하고 작동하지 않는지 잘 모르겠습니다.지금까지 윈도우즈 PowerShell, 명령 프롬프트 및 ConHost는 모두 이를 허용합니다.Linux에서 텍스트를 색으로 표시하는 방법을 잘 모르거나 이전 버전의 Windows(윈도우)에서 이 방법이 작동하는지도 알 수 없습니다.

언급URL : https://stackoverflow.com/questions/51680709/colored-text-output-in-powershell-console-using-ansi-vt100-codes

반응형