重要的
Windows Terminal 1.18 版的新进程模型需要不同的方法。
请参阅 https://github.com/german-one/termwnd 了解新的实现。
此存储库中代码的目的是区分 Conhost 和 Windows 终端进程,并确定哪个终端实例连接到当前控制台进程。不支持第三方终端应用程序。
源文件是几乎相同的核心代码在不同编程语言中的转录。
Windows Batch
、 C
、 C++
、 C#.Net
、 PowerShell
和VB.Net
中的源文件发布在 src 文件夹中。它们都依赖于 Windows 作为目标操作系统。下面列出了其他特定的依赖项。
文件 | 要求 |
---|---|
*.bat | Windows PowerShell 2 |
*.c | C99 |
*.cpp | C++20 |
*.cs | .NET框架4.5 |
*.ps1 | Windows PowerShell 2 |
*.vb | .NET框架4.5 |
此存储库中的源文件包含功能齐全的代码,演示如何使用搜索过程。但是,如果您打算在自己的代码中使用它,那么了解需要包含哪些基本代码片段可能会很有用。
文件 | 兴趣代码 | 利息价值 |
---|---|---|
*.bat | :init_TermPid 例程中定义的TermPid 宏 | TermPid 宏返回的错误级别是托管终端的 PID(如果发生错误则为0 ) |
*.c | GetTermPid 函数,以及结构SYSTEM_HANDLE 和函数GetProcBaseName 、 GetPidOfNamedProcWithOpenProcHandle | GetTermPid 函数返回的值是托管终端的 PID(如果发生错误则为0 ) |
*.cpp | 命名空间termpid 中的所有内容,以及命名空间saferes 和GetProcBaseName 函数 | GetTermPid 函数返回的值是托管终端的PID(如果发生错误则为0 或异常) |
*.cs | WinTerm 班 | 属性WinTerm.TermProc 的值指的是托管终端进程(如果发生错误则为null 或异常) |
*.ps1 | 类型引用类WinTerm | 属性[WinTerm]::TermProc 的值指的是托管终端进程(如果发生错误,则$null 或类型WinTerm 未定义) |
*.vb | 模块WinTerm | 属性WinTerm.TermProc 的值指的是托管终端进程(如果发生错误则Nothing 或异常) |
几年前微软开始开发一种新的终端应用程序——Windows Terminal。该安装适用于 Windows 10,Windows 11 已附带该安装。通过 22 年 10 月的更新,微软将其变成了 Windows 11 上的默认终端应用程序。
截至目前,Windows Terminal 与旧的 Conhost 共存。用户可以选择将哪个应用程序作为默认终端应用程序。
过去,很容易找出哪个终端进程连接到 shell/控制台应用程序。在幕后它始终是 Conhost,因此,Microsoft 让 Windows API 将生成 conhost 进程的进程报告为终端进程,并将 shell 应用程序的窗口报告为控制台窗口。虽然这一切在技术上都是不正确的,但同时却相当舒适。
但是,Windows 终端没有实现此类便利功能。如果Windows Terminal被设置为默认终端,我们就无法从进程树推断哪个终端进程正在与我们的shell进程通信。
使用 Process Explorer,我观察到 Windows 终端进程有一个打开的 shell 进程的句柄。假设情况总是如此,我尝试编写一段代码来枚举所有打开的句柄,以搜索正确的进程句柄。这就需要涉及到一些未公开的API。我在代码中留下了一些注释,大致解释了这一切是如何工作的。
每个文件中还有一段不相关的代码,用于使窗口淡出并再次淡入。我发现这是一种令人印象深刻的方式来证明已经找到了正确的流程。
这是对如何在源代码中实现搜索的简要说明。
NtQuerySystemInformation
API 函数用于获取所有正在运行的进程中所有打开句柄的快照。 (这没有正式记录。)