Welcome to the Windows Console documentation!

Windows Console and Terminal Ecosystem Roadmap

提到了两个产品Windows Console和Windows Terminal。 目的是清退,旧的API。代之以仿冒控制台的虚拟终端序列。

Architecture

分为四部分

  • client
    • 命令行应用,使用基于文本的界面来获取用户输入和提供输出。Console API提供了一个client到device的通信层。
  • Device
    • 一个中间的、在两个进程(client和server)之间的消息处理层。比如TTY或PTY设备。如果整个交易是纯文本的或者包含虚拟终端序列,则可以使用其他如文件、管道和套接的方式作为通信频道。而不需要经过Console API。
  • Server
    • 处理从client来的API请求和消息。在旧模式下,server还创建一个用户界面用于向屏幕提供输出。此外,server还通过driver收集输入以返回给client。控制台仿冒模式下,server只是一个虚拟终端序列的翻译器。
  • Terminal
    • 提供图形化显示给用户。负责获取输入并录编为虚拟终端序列,最终会到底client的STDIN,同时也会将client的STDOUT输出到屏幕。

不同的应用可以串在一起,比如SSH。对于非Windows平台,server和terminal通常是一体的,因为没有必要对API和虚拟终端序列做翻译。

Microsoft products

Windows Console Host是传统的命令行应用的用户界面,处理所附着的命令行应用的所有的控制台API。在系统目录总通常以conhost.exe和openconsole.exe出现(后者可以处理控制台仿冒)。扮演的是server-terminal、或者仅仅是server的角色。

Windows Terminal是新的命令行应用的接口,提供控制台仿冒功能,以分离API供货和文件显示接口,类似于Windows以外的平台。

Major historical milestones

一开始console host仿真实现了DOS环境,代码在cmd.exe内。

而后为中日韩实现了DBCS。

为了安全运行在csrss.exe中,console子系统分为不同的应用,每个具有不同的权限级别。

添加了 line selection, smooth window resizing, reflowing text, copy and paste, high DPI support, Unicode等支持。

随着WSL、Docker、OpenSSH在Windows平台的兴起。开始着手实现https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences。允许现有控制台用作终端,直接连结(attach)到Linux原生的程序中去。

引入了https://docs.microsoft.com/en-us/windows/console/pseudoconsoles,允许任意应用以非交互模式加载console host。

Roadmap for the future

Windows Termainl是对这些控制台新特性的明星示例。

在Windows操作系统内,Windows Terminal,ConPTY和virtual terminal sequences将会成为主流,原先的console host将会退居二线:https://docs.microsoft.com/en-us/windows/console/classic-vs-vt

推荐client优先使用https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences而不是老的接口。但是目前windows还缺乏诸如readline、ncurser这样的辅助料库。

何时能够抛弃https://docs.microsoft.com/en-us/windows/console/console-functions,还是一个谜。

Consoles

控制台是一个应用,为其他字符模式的应用提高I/O服务。

控制台有一个输入缓冲,和若干个屏幕缓冲。输入缓冲有一个输入记录的队列,每个对应一个输入事件,包含按键下压和按键释放等事件,也可以包含鼠标事件,还可以包含其他事件。屏幕缓冲是一个二维数组,元素包含字符和颜色。

多个进程可以共享一个控制台。

Pseudoconsoles

一个仿冒控制台是一个设备类型,允许应用自身成为字符模式应用的宿主。而不是以前,需要操作系统创建一个宿主窗口。

底下依然会创建控制台会话,任何关于控制台会话的规则也适用。仿冒控制台的通信采用的是UTF-8编码,会自动和客户程序的编码页进行转化。

参考https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/

Using the Console

Creating a Pseudoconsole session

伪品控制台会话和传统控制台会话不不同。传统控制台会话会自动创建,只要操作系统识别是一个字符模式的应用程序要运行。而伪品会话需要宿主自己创建。

Preparing the communication channels

其实跟nix上的蛮像的,都是要创建两个文件描述符,然后通过文件读写来操作。

具体到Windows,就是要以同步IO方式采用ReadFile以及WriteFile。

也就是说,只要不采用异步相关OVERLAPPED即可。

为了避免竞争条件和死锁,推荐每个通信频道在单独的线程上,具有自己的客户端缓存。在单一线程线程上处理所有的通信有可能导致死锁,特别当一个通信缓存满了,处于等待行动状态,然后你尝试在另一个通信频道上转派一个阻塞的请求。

Creating the Pseudoconsole

窗口的尺寸可以用https://docs.microsoft.com/en-us/windows/console/console-functions控制,比如GetConsoleScreenBufferInfoEx和WriteConsoleOutput。

参考

网络文摘

Capturing console I/O in Win32

Windows NT 10,可以让你使用CreatePseudoConsole,然后使用管道相连。创建子进程的时候需要指定一个特殊标记来连结pseudo-console。通信使用的是ECMA-48格式的文本。

As an aside: there is no distinction between DOS and Win32 console applications here. On Windows NT, the case of DOS applications is actually a subset of the more general case of “console mode” applications, because DOS applications run (on those 32-bit versions of Windows NT that still support this) as coroutines within a Win32 process (NTVDM) that translates their I/O to Win32 console I/O equivalents.

这篇文章的剩余部分也值得一读,讲述了high-level api和low-level api所导致的问题。

使用老的API

在没有ConPTY的日子里,WinPTY默默承担相应的角色。

(未完待续))