Linux命令行厉害,其实Windows的也很强(3)
小白说:很多人说“命令行程序在控制台运行”。这不是真的,而且导致很多关于控制台和命令行应用程序如何工作的困惑!命令行应用程序和它们的控制台都在各自独立的 Win32 进程中运行。请通过指出“命令行工具/应用程序连接到控制台运行”(或类似的)来帮助纠正这种误解。谢谢! 听起来不错,对吧?嗯…不;这里有一些问题: 1.控制台和命令行应用程序通过经由驱动程序的 IOCTL 消息进行通信,而不是通过文本流进行通信 2.windows 要求 ConHost.exe 必须是连接到命令行应用程序的控制台程序 3.Windows 控制了控制台和命令行应用程序通信之间通信“管道”的创建 这些都是明显的限制:如果你想为 Windows 创建一个替代控制台的应用程序,该怎么办?你将如何发送键盘、鼠标、笔等等外设的信息?如果你无法访问连接你新控制台和命令行应用程序的通信“管道”,用户将怎么对命令行应用程序进行操作? 遗憾的是,这些情况并不好:有一些很棒的用于 Windows 的第三方控制台(和服务器应用程序)(例如 ConEmu/Cmder, Console2/ConsoleZ, Hyper, Visual Studio Code, OpenSSH 等),他们必须通过离奇的跳转才能像正常的控制台一样运行! 举例来说,第三方控制台必须在屏幕外启动一个命令行应用程序,例如(-32000,-32000)。然后,他们必须向屏幕外控制台发送击键信息,然后收集屏幕外控制台的文本内容并在自己的 UI 上重新绘制它们! 我知道,这很疯狂,对吧? !这证明了这些应用程序创造者们的独创性和决心,这些程序甚至还在有效的运行! 这显然是我们急于补救的一种情况。请继续关注这部分内容的更多信息——在这方面有一些好消息! Windows 控制台 & VT 如上所述,Windows 控制台提供了大量 API。使用控制台 API,命令行应用程序和工具可写入文本,更改文本颜色,移动光标等。并且,由于控制台 API 的存在,Windows 控制台几乎不需要支持 ANSI/VT 序列,这些序列在其他平台上提供非常类似的功能。 实际上,在 Windows 10 之前,Windows 控制台仅实现了对 ANSI/VT 序列的最低限度支持: 从2014年开始,微软组建了一个新的 Windows 控制台团队,使得这一切都发生了变化。控制台团队的最高优先级事项之一是实现对 ANSI/VT 序列的全面支持,以便渲染在 Windows 子系统之Linux(WSL)和远程 *NIX 机器上运行的 *NIX 应用程序的输出。您可以在本系列的上一篇文章中阅读更多关于这个故事的内容。 控制台团队迅速为 Windows 10 的控制台添加了对 ANSI/VT 序列的全面支持,使用户能够使用和享用大量 Windows 和 Linux 命令行工具和应用程序。 该团队继续改进和完善每个操作系统发布版本上的控制台对 VT 的支持,并对您在我们的 GitHub 问题跟踪器上提交的任何问题表示感谢。 处理Unicode 一个快速的Unicode回顾: Unicode或ISO/IEC 10646是一个国际标准,定义了地球上几乎每个书写系统中所使用的每个字符/字形,以及当今使用的许多非脚本符号和字符大小的图像(例如表情符号)。目前(2018年7月),Unicode 11定义了137439个字符,包含146个现代和历史文字系统! Unicode还定义了几种字符编码,包括UTF-8, UTF-16, 和UTF-32:
由于UTF-8的高效的存储要求以及在HTML页面中的广泛使用,它是目前最流行的编码。 UTF-16/UCS-2都是常见的,尽管在已存储文档(例如网页、代码等)中其使用比例正在降低。UTF-32是很少使用的,因为它的效率低且存储需要相当大的空间。 很好,所以我们有有效并且高效的方式来表示和存储Unicode字符了! 所以? 哎呀,Windows控制台及其API是在创建Unicode之前创建的! Windows控制台将文本(随后在屏幕上绘制)存储为每个单元需要2个字节的UCS-2字符。 命令行应用程序使用控制台API将文本写入到控制台中。处理文本的控制台API有两种形式 - 带有A后缀处理的单字节/字符串的函数,带有W后缀处理双字节(wchar)/字符串的函数: 例如,WriteConsoleOutputCharacter()函数编译为ASCII项目的WriteConsoleOutputCharacterA(),或Unicode项目的WriteConsoleOutputCharacterW()。如果需要指定处理方式,代码中可以直接调用... A或...W后缀的函数。 注意:每个W API至少支持UCS-2,因为这是在进行A/W拆分时就存在的事情,我们认为这样做会很棒。但许多W API已更新为在同一渠道上也支持UTF-16。并非所有W API都可以支持UTF-16,但所有W API至少可以支持UCS-2。 此外,控制台不支持一些较新的Unicode功能,包括零宽度连接符(ZWJ),该符号被用于连接阿拉伯语和印度语中的其他单独字符,并将表情符号字符组合成一个可视字形! 那么如果你想在控制台上输出一个ninjacat表情符号或复杂的多字节中文/阿拉伯字符会怎样呢? 糟糕的是,你做不到! Console API不仅不支持长度超过2字节/字形的Unicode字符(NinjaCat表情符号需要8个字节!),但Console内部的UCS-2缓冲区不能存储该数据的额外字节,更糟糕的是 ,Console当前的基于GDI的渲染器甚至无法绘制字形,即使缓冲区可以存储它! 可叹! 这就是遗留代码的乐趣。 但是,我也会希望你们到此打住 - 我们将在本系列的新一篇文章中回到这个主题。 敬请关注! 所以,我们在哪里?再一次,亲爱的读者,如果你读过以上的所有内容,谢谢你,也祝贺你 —— 你现在比你的大多数朋友都更了解 Windows 控制台,甚至可能比你想知道的还要多!祝你幸运! 在这篇文章中,我们涵盖了很多内容: (编辑:ASP站长网) |