Windows Command-Line: Introducing the Windows Pseudo Console (ConPTY)

https://en.wikipedia.org/wiki/Pseudoterminal是Nix平台的常见服务。

From TTY to PTY

electromechanical Teletype (TTY) device were replaced by computerized Terminals with electronic display devices (usually CRT screens)

But a problem arose: How would a Terminal application speak to another Command-Line application running on the same machine? And how would you attach a physical serial cable between the two apps running on the same computer?

简单说,非windows平台使用更灵活的text/VT,而windows平台使用API。

之前,这些程序ConEmu/Cmder, Console2/ConsoleZ, Hyper, VSCode, Visual Studio, WSL, Docker, OpenSSH都是使用API,然后将生成的Console窗口隐藏起来。

Welcome, to the Windows Pseudo Console (ConPTY)

大修过后的ConHost支持所有的命令行应用以及GUI应用。

看架构图,还是蛮复杂的。为仿冒控制台提供了以下功能

  • ConPTY API
  • VT Interactivity
  • VT Renderer

命令行应用加载后,会通过ConDrv(IOCTL)连结到一个控制台(ConHost.exe)实例。它们的STDIN/STDOUT会继承自上级进程。

The app and its Console instance are connected via the kernel-mode Console Driver (ConDrv) which sends/receives IOCTL messages containing serialized API call requests and/or text data

When a Command-Line app calls Windows Console APIs, the API calls are serialized into IOCTL messages and sent via the ConDrv driver.

ConHost现在提供PTY服务。

OpenSSH在Win10被移植到了Windows:https://github.com/PowerShell/Win32-OpenSSH,作为远程Shell。

sshd也支持了。

The ConPTY API and how to use it

接口共有三个

  • CreatePseudoConsole
    • 设定仿品控制台的尺寸、输入、输出以及控制旗标
    • 获得HPCON*
  • ResizePseudoConsole
  • ClosePseudoConsole

示例代码https://github.com/Microsoft/console/tree/master/samples/ConPTY/EchoCon。简单地说:

  • 创建两个管道做为输入和输出
  • 创建一个仿品控制台
  • 初始化启动信息
  • 创建子进程

给仿品输入数据的话,只要使用WriteFile即可。

Call To Action!

对于新命令行程序,推荐使用UTF-8录编的text/VT与仿品台通信,可以支持更多特性。

对于控制台、终端应用,强烈建议使用新的ConPTY用编口。

ConPTY在Win10 2018秋季中可用(1809?)。可以使用LoadLibrary() & GetProcAddress()来测试API是否存在。

C#的例子

ConPTY自身的代码在:https://github.com/microsoft/terminal/tree/main/src/winconpty

Windows Console反馈用的仓库:https://github.com/microsoft/console

https://conemu.github.io/是一个第三方控制台应用。

(未完待续)