클래식 Windows 콘솔 API 를 가상 터미널 시퀀스로 바꾸는 것이 좋습니다. 이 문서에서는 두 항목의 차이점을 간략하게 설명하고 권장 사항의 이유를 설명합니다.
정의
클래식 Windows 콘솔 API 화면은 이름에 kernel32.dll "콘솔"이 있는 일련의 C 언어 기능 인터페이스로 정의됩니다.
가상 터미널 시퀀스는 표준 입력 및 표준 출력 스트림에 포함된 명령의 언어로 정의됩니다. 가상 터미널 시퀀스는 일반 인쇄 가능 텍스트와 인터리브된 신호 명령에 인쇄할 수 없는 이스케이프 문자를 사용합니다.
역사
Windows 콘솔은 클라이언트 명령줄 애플리케이션이 출력 표시 버퍼와 사용자 입력 버퍼를 모두 조작할 수 있는 광범위한 API 화면을 제공합니다. 그러나 다른 비 Windows 플랫폼은 표준 입력 및 표준 출력 스트림 내에 포함된 가상 터미널 시퀀스를 대신 사용하도록 선택하여 명령줄 환경에 이 특정 API 기반 접근 방식을 제공한 적이 없습니다. (한동안 Microsoft는 ANSI.SYS이라는 드라이버를 통해 DOS 및 Windows의 초기 버전에서도 이 동작을 지원했습니다.)
반면, 가상 터미널 시퀀스 (다양한 방언)는 다른 모든 플랫폼에 대한 명령줄 환경 작업을 구동합니다. 이러한 시퀀스는 여러 공급업체가 확장한 ECMA 표준과 일련의 확장에서 출발하며, 이는 Digital Equipment Corporation과 Tektronix 터미널에 뿌리를 두고, 현대적이고 일반적인 소프트웨어 터미널인 xterm으로 이어집니다. 가상 터미널 시퀀스 도메인 내에 많은 확장이 존재하며 일부 시퀀스는 다른 시퀀스보다 더 널리 지원되지만, 사실상 모든 터미널 및 명령줄 클라이언트 애플리케이션에서 지원되는 잘 알려진 하위 집합이 있는 명령줄 환경을 위한 명령 언어로 이를 표준화했다고 해도 안전합니다.
플랫폼 간 지원
가상 터미널 시퀀스는 기본적으로 플랫폼 간에 지원되므로 Windows를 제외한 운영 체제 버전과 변형 간에 터미널 애플리케이션 및 명령줄 유틸리티를 쉽게 이식할 수 있습니다.
반면 Windows 콘솔 API는 Windows 에서만 지원됩니다. Windows와 가상 터미널 간에 광범위한 어댑터 또는 번역 라이브러리를 작성하거나 그 반대로 한 플랫폼 또는 다른 플랫폼에서 명령줄 유틸리티를 포팅하려고 할 때 작성해야 합니다.
원격 액세스
가상 터미널 시퀀스는 원격 액세스에 큰 이점을 제공합니다. 표준 원격 명령줄 연결을 설정하는 데 필요한 작업 외에 전송이나 원격 프로시저 호출을 수행하기 위해 추가적인 작업이 필요하지 않습니다. 파이프, 소켓, 파일, 직렬 포트 또는 기타 디바이스를 통해 아웃바운드 및 인바운드 전송 채널(또는 단일 양방향 채널)을 연결하는 것만으로도 이러한 시퀀스를 말하는 애플리케이션에 필요한 모든 정보를 원격 호스트에 완전히 전달하기에 충분합니다.
반대로 , Windows 콘솔 API 는 로컬 컴퓨터에서만 액세스할 수 있으며, 원격으로 연결하려는 모든 노력에는 단순한 채널 이상의 전체 원격 통화 및 전송 인터페이스 계층을 빌드해야 합니다.
문제의 분리
일부 Windows 콘솔 API는 대화형 명령줄에 대한 입력 및 출력 버퍼 또는 편리한 함수에 대한 낮은 수준의 액세스를 제공합니다. 여기에는 명령줄 클라이언트 애플리케이션 자체가 아닌 콘솔 하위 시스템 및 호스트 환경 내에서 프로그래밍된 별칭 및 명령 기록이 포함될 수 있습니다.
반면 , 다른 플랫폼은 애플리케이션의 현재 상태와 편의 기능에 대한 메모리를 명령줄 유틸리티 또는 셸 자체의 책임으로 만듭니다.
콘솔 호스트 및 API에서 이 책임을 처리하는 Windows 콘솔 방법을 사용하면 이러한 기능을 사용하여 명령줄 애플리케이션을 더 빠르고 쉽게 작성할 수 있으므로 그리기 상태를 기억하거나 편집 편의 기능을 처리할 책임이 없습니다. 그러나 구현 및 가용성의 변화로 인해 플랫폼, 버전 또는 시나리오에서 이러한 활동을 원격으로 연결하는 것은 거의 불가능합니다. 또한 이러한 책임 처리 방법은 이러한 Windows 명령줄 애플리케이션의 최종 대화형 환경을 콘솔 호스트의 구현, 우선 순위 및 릴리스 주기에 완전히 종속합니다.
예를 들어 구문 강조 표시 및 복잡한 선택과 같은 고급 줄 편집 기능은 명령줄 애플리케이션이 편집 문제를 처리하는 경우에만 가능합니다. 콘솔에는 클라이언트 애플리케이션과 같은 광범위한 방식으로 이러한 시나리오를 완전히 이해할 수 있는 충분한 컨텍스트가 있을 수 없습니다.
반면, 다른 플랫폼은 가상 터미널 시퀀스를 사용하여 읽기 라인 및 ncurses와 같은 재사용 가능한 클라이언트 쪽 라이브러리를 통해 이러한 활동 및 가상 터미널 통신 자체를 처리합니다. 최종 터미널은 정보를 표시하고 해당 양방향 통신 채널을 통해 입력을 수신하는 작업만 담당합니다.
Wrong-Way 동사
Windows 콘솔을 사용하면 입력 및 출력 스트림에서 반대 방향과 자연스러운 방향으로 일부 작업을 수행할 수 있습니다. 이를 통해 Windows 명령줄 애플리케이션은 자체 버퍼를 관리하는 문제를 방지할 수 있습니다. 또한 Windows 명령줄 앱은 사용자를 대신하여 입력을 시뮬레이트/삽입하거나 기록된 내용의 일부 기록을 다시 읽는 등의 고급 작업을 수행할 수 있습니다.
이렇게 하면 단일 컴퓨터의 특정 사용자 컨텍스트에서 작동하는 Windows 애플리케이션에 추가 기능을 제공하지만 특정 시나리오에서 사용할 때 보안 및 권한 수준 또는 도메인을 교차하는 벡터도 제공합니다. 이러한 시나리오에는 동일한 컴퓨터의 컨텍스트 간 또는 다른 컴퓨터 또는 환경에 대한 컨텍스트 간 작동이 포함됩니다.
가상 터미널 시퀀스를 사용하는 다른 플랫폼은 이 작업을 허용하지 않습니다. 클래식 Windows 콘솔에서 가상 터미널 시퀀스로 전환하기 위한 권장 사항은 상호 운용성과 보안상의 이유로 이 전략을 수렴하는 것입니다.
직접 창 액세스
Windows 콘솔 API 화면 은 호스팅 창에 대한 정확한 창 핸들을 제공합니다. 이를 통해 명령줄 유틸리티는 창 핸들에 대해 허용되는 Win32 API의 넓은 영역으로 이동하여 고급 창 작업을 수행할 수 있습니다. 이러한 Win32 API는 창 상태, 프레임, 아이콘 또는 창에 대한 기타 속성을 조작할 수 있습니다.
반면, 가상 터미널 시퀀스가 있는 다른 플랫폼에서는 창에 대해 수행할 수 있는 명령 집합이 좁습니다. 이러한 명령은 창 크기 또는 표시된 제목 변경과 같은 작업을 수행할 수 있지만 스트림의 나머지 부분과 동일한 대역 및 동일한 컨트롤에서 수행해야 합니다.
Windows가 발전함에 따라 창 핸들에 대한 보안 제어 및 제한이 증가했습니다. 또한 특정 사용자 인터페이스 요소에 대한 애플리케이션 주소 지정 가능 창 핸들의 특성과 존재는 특히 디바이스 폼 팩터 및 플랫폼의 지원 증가와 함께 발전했습니다. 따라서 플랫폼 및 환경이 발전함에 따라 명령줄 애플리케이션에 대한 직접 창 액세스가 취약해집니다.
유니코드
UTF-8은 이식성, 스토리지 크기 및 처리 시간 사이의 적절한 균형을 맞추기 때문에 거의 모든 최신 플랫폼에서 유니코드 데이터에 허용되는 인코딩입니다. 그러나 Windows는 지금까지 유니코드 데이터에 대한 기본 인코딩으로 UTF-16을 선택했습니다. WINDOWS에서 UTF-8에 대한 지원이 증가하고 있으며 이러한 유니코드 형식을 사용하면 다른 인코딩을 사용할 수 없습니다.
Windows 콘솔 플랫폼은 지원되며 모든 기존 코드 페이지 및 인코딩을 계속 지원합니다. Windows 버전 간 호환성을 극대화하려면 UTF-16을 사용하고 필요한 경우 UTF-8을 사용하여 알고리즘 변환을 수행합니다. 콘솔 시스템에 대한 UTF-8의 지원 증가가 진행 중입니다.
콘솔의 UTF-16 지원은 모든 콘솔 API의 W 변형을 통해 추가 구성 없이 활용할 수 있으며, 다른 Microsoft 및 Windows 플랫폼 기능 및 제품의 wchar_t 변형과의 통신을 통해 이미 UTF-16에 정통한 애플리케이션에 더 적합합니다.
콘솔의 UTF-8 지원은 또는 65001 코드페이지를 CP_UTF8 및 SetConsoleCP 메서드를 사용하여 설정한 후 콘솔 핸들에 대해 콘솔 API의 A 변형을 통해 활용할 수 있습니다. 제어판의 지역 섹션에서 유니코드가 아닌 애플리케이션에 대한 설정에서 컴퓨터가 "전 세계 언어 지원에 유니코드 UTF-8 사용"을 선택하지 않은 경우에만 코드 페이지를 미리 설정해야 합니다.
비고
현재 UTF-8은 WriteConsole 및 WriteFile 메서드를 사용하여 표준 출력 스트림에서 완전히 지원됩니다. 입력 스트림에 대한 지원은 입력 모드에 따라 다르며 시간이 지남에 따라 계속 개선됩니다. 특히 입력의 기본 "익은" 모드는 아직 UTF-8을 완전히 지원하지 않습니다. 이 작업의 현재 상태는 GitHub의 microsoft/terminal#7777 에서 찾을 수 있습니다. 해결 방법은 미해결 문제가 해결될 때까지 ReadConsoleW 또는 ReadConsoleInputW를 통해 입력을 읽기 위해 알고리즘 으로 변환 가능한 UTF-16을 사용하는 것입니다.
권장 사항
Windows의 모든 신규 및 지속적인 개발의 경우 터미널과 상호 작용하는 방법으로 가상 터미널 시퀀스를 사용하는 것이 좋습니다 . 이렇게 하면 Windows 명령줄 클라이언트 애플리케이션이 다른 모든 플랫폼에서 애플리케이션 프로그래밍 스타일로 수렴됩니다.
Windows 콘솔 API 사용에 대한 예외
초기 환경을 설정 하려면 Windows 콘솔 API의 제한된 하위 집합이 여전히 필요합니다 . Windows 플랫폼은 프로세스, 신호, 디바이스 및 인코딩 처리의 다른 플랫폼과 여전히 다릅니다.
프로세스에 대한 표준 핸들은 GetStdHandle 및 SetStdHandle을 사용하여 계속 제어됩니다.
가상 터미널 시퀀스 지원을 옵트인하는 핸들의 콘솔 모드 구성은 GetConsoleMode 및 SetConsoleMode를 사용하여 처리됩니다.
코드 페이지 또는 UTF-8 지원 선언은 SetConsoleOutputCP 및 SetConsoleCP 메서드를 사용하여 수행됩니다.
콘솔 디바이스 세션에 참가하거나 나가려면 AllocConsole, AttachConsole 및 FreeConsole 에서 일부 수준의 전체 프로세스 관리가 필요할 수 있습니다.
SetConsoleCtrlHandler, HandlerRoutine 및 GenerateConsoleCtrlEvent를 사용하여 신호 및 신호 처리를 계속 수행합니다.
콘솔 디바이스 핸들과의 통신은 WriteConsole 및 ReadConsole 을 사용하여 수행할 수 있습니다. CRT(C 런타임): printf, scanf, putc, getc 또는 기타 수준의 I/O 함수와 같은 스트림 I/O 형식의 프로그래밍 언어 런타임을 통해 활용할 수도 있습니다. - C++ STL(표준 라이브러리): cout 및 cin과 같은 iostream입니다. - .NET 런타임: Console.WriteLine과 같은 System.Console입니다.
창 크기 변경 사항을 수신해야 하는 애플리케이션은 키 이벤트와 섞여 있는 해당 변경 사항들을 받기 위해 여전히 ReadConsoleInput을 사용해야 합니다. 왜냐하면 ReadConsole 단독으로는 그들을 처리하지 않기 때문입니다.
열, 그리드를 그리거나 디스플레이를 채우려는 애플리케이션의 경우 GetConsoleScreenBufferInfo 를 사용하여 창 크기를 찾아야 합니다. 창 및 버퍼 크기는 의사 콘솔 세션에서 일치합니다.
향후 계획 및 의사 콘솔
플랫폼에서 Windows 콘솔 API를 제거할 계획은 없습니다.
반대로, Windows 콘솔 호스트는 기존 Windows 명령줄 애플리케이션 호출을 가상 터미널 시퀀스로 변환하여 원격으로 또는 플랫폼 간에 다른 호스팅 환경으로 전달하는 가상 콘솔 기술을 제공했습니다.
이 번역은 완벽하지 않습니다. Windows가 사용자에게 표시할 시뮬레이션된 환경을 유지하려면 콘솔 호스트 창이 필요합니다. 그런 다음 이 시뮬레이션된 환경의 복제본을 pseudoconsole (의사 콘솔) 호스트에 투영합니다. 모든 Windows 콘솔 API 호출은 레거시 명령줄 클라이언트 애플리케이션의 요구를 충족하기 위해 시뮬레이션된 환경 내에서 작동합니다. 효과만 최종 호스트로 전파됩니다.
따라서 플랫폼 간에 완전한 호환성을 제공하고 Windows 및 다른 위치에서 모든 새로운 기능과 시나리오를 완전히 지원하는 명령줄 애플리케이션은 가상 터미널 시퀀스로 이동하고 모든 플랫폼에 맞게 명령줄 애플리케이션의 아키텍처를 조정하는 것이 좋습니다.
명령줄 애플리케이션에 대한 이 Windows 전환에 대한 자세한 내용은 에코시스템 로드맵에서 확인할 수 있습니다.