我经常对 Windows 的控制台主机应用程序感到失望,尤其是剪贴板的笨拙工作、没有自动宽度问题等等。我想知道是否有办法用自定义控制台主机替换默认控制台主机,conhost.exe
以及如果我要编写自己的控制台主机,在哪里可以找到有关我必须实现的接口的更多信息。
我并不是在寻找一个替代控制台,我已经xterm
在 CygWin 中使用了它。我正在寻找有关如何代替Windows 的默认控制台窗口主机。
答案1
下面是一些比 cmd 更加用户友好的控制台替代产品。
如下文所述,自 Windows 7 以来,所有这些 shell 都只是 conhost.exe 的接口,甚至 powershell 也是如此。有关详细信息,请阅读conhost.exe 是什么以及它为什么运行。
因此,下面的控制台仅替代了 conhost 的默认可视化界面(即 cmd 所展示的界面),并且仅在作为程序直接调用时才有用。它们不能被间接调用,例如当运行 diskpart 等控制台可执行文件时,因为这将调用 conhost,而 conhost 有自己的 I/O 接口和 API。
以下是微软的说法Windows 7 / Windows Server 2008 R2:控制台主机:
ConHost 代表了控制台应用程序 I/O 处理方式的永久性改变。没有注册表项或组策略设置可以强制 Windows 恢复到“传统模式”控制台行为。
结论是,如果你想要比替换 cmd 界面更深入地替换控制台,那么这是不可能的。微软选择这种设计是出于安全考虑,不会再回头了。
我能想到的唯一改变 conhost 行为的方式是在 conhost API 上设置一个全局系统钩子。我完全不知道这是否可行,到目前为止还没有人这样做过(或者如果他们这样做了他们没有告诉)。我也不相信微软会让你用破解版替换像 conhost.exe 这样至关重要的系统文件。
如果需要替换位于 system32\cmd.exe 中的 cmd,则需要获取该文件的所有权,然后重命名它(cmd1.exe?),将控制台替换 exe 重命名为 cmd.exe,并将其与运行所需的所有文件一起复制到 system32。如果替换控制台不支持 cmd 支持的所有参数,这可能会导致问题。
另一种适用于 .bat 文件的方法是将新控制台与它们关联。为此,需要编辑注册表项HKEY_CLASSES_ROOT\batfile\shell\open\command
。请参阅此文章了解详细信息。
以下是控制台的列表:
答案2
有类似这样的项目安慰它包裹着 cmd.exe,可能可以满足您的需求,但我还没有看到任何可以完全替代控制台系统的东西。据我所知,大多数此类项目只是重定向 stdin/stdout/stderr,然后包裹一个更常见的 GUI 包裹 cmd.exe,将实际的控制台窗口隐藏在后台。
答案3
微软已经发布了他们的 conhost.exe 源代码(https://github.com/microsoft/terminal)。
此存储库中的控制台主机代码是构建 Windows 本身中的 conhost.exe 的实际源。
所以现在你有机会在 Windows 10 中用自己的控制台主机替换默认的 conhost.exe。事实上,我已经做过这样的尝试,并取得了成功(https://github.com/microsoft/terminal/issues/1817)。
然后微软说OpenConsole的源代码来自于conhost.exe,那么我们能不能直接用OpenConsole.exe替换conhost.exe呢?这样我们就得到了一个更好的默认控制台主机。
我试了一下,效果很好。虽然 OpenConsole 被打包为 UWP 应用程序,但 OpenConsole.exe 实际上是普通的 Win32 窗口程序,可以通过双击其 exe 来运行。如果您完成了 x64 发布版本,则可以从 terminal\bin\x64\Release\OpenConsole.exe 中找到它。
然后,进入C:\Windows\System32,右键点击conhost.exe,“属性”,编辑权限列表,赋予当前用户“完全控制”权限。
然后,将 conhost.exe 重命名为 conhost-old.exe,并将 OpenConsole.exe 复制到此处并将其重命名为 conhost.exe。
打开任何控制台应用程序(powershell、wsl 等)并享受您的新控制台。
还可以将 OpenConsole 源代码移植到 Windows 7。此外,因为您拥有源代码,所以您可以添加任何您想要的功能。
此外微软还在Windows 10中引入了Windows Pseudo Console API,让开发者可以更加优雅的开发第三方终端应用(没错,就是通过conhost.exe实现的,应该包含在微软发布的代码中)。
conhost.exe 实际上负责以下事项:
(从https://devblogs.microsoft.com/commandline/windows-command-line-inside-the-windows-console/)
控制台的核心组件包括以下内容(从下至上):
ConDrv.sys – 内核模式驱动程序
- 在控制台和任何连接的命令行应用程序之间提供高性能通信通道
- 在命令行应用程序和它们“附加”的控制台之间来回传递 IO 控制 (IOCTL) 消息
- 控制台 IOCTL 消息包含
- 表示针对控制台实例执行 API 调用的请求的数据
- 从控制台发送到命令行应用程序的文本
ConHost.exe – Win32 GUI 应用程序:
ConHost Core – 控制台的内部结构和管道
- API 服务器:将从命令行应用程序收到的 IOCTL 消息转换为 API 调用,并将文本记录从控制台发送到命令行应用程序
- API:实现 Win32 控制台 API 以及控制台可以执行的所有操作背后的逻辑
- 输入缓冲区:存储用户输入产生的键盘、鼠标事件记录
- VT 解析器:如果启用,则从文本中解析 VT 序列,从文本中提取任何找到的序列,并生成等效的 API 调用
- 输出缓冲区:存储控制台显示屏上显示的文本。本质上是 CHAR_INFO 结构的二维数组,其中包含每个单元的字符数据和属性(有关缓冲区的更多信息,请参见下文)
- 其他:上图中未包括从注册表和/或快捷方式文件等存储/检索值的设置基础设施。
控制台 UX 应用服务 – 控制台 UX 和 UI 层
- 管理屏幕上控制台窗口的布局、大小、位置等
- 显示和处理设置UI等。
- 抽取 Windows 消息队列,处理 Windows 消息,并将用户输入转换为键和鼠标事件记录,并将其存储在输入缓冲区中