ВАЖНЫЙ
Новая модель процессов Windows Terminal версии 1.18 требует другого подхода.
См. https://github.com/german-one/termwnd для новой реализации.
Цель кода в этом репозитории — различать процессы Conhost и Windows Terminal, а также определять, какой экземпляр терминала подключен к текущему консольному процессу. Сторонние терминальные приложения не поддерживаются.
Исходные файлы представляют собой транскрипции практически одного и того же основного кода на разных языках программирования.
Исходные файлы в Windows Batch
, C
, C++
, C#.Net
, PowerShell
и VB.Net
публикуются в папке src. Все они зависят от того, является ли Windows целевой операционной системой. Другие конкретные зависимости перечислены ниже.
Файл | Требование |
---|---|
*.bat | Windows PowerShell 2 |
*.c | С99 |
*.cpp | С++20 |
*.cs | .NET Framework 4.5 |
*.ps1 | Windows PowerShell 2 |
*.vb | .NET Framework 4.5 |
Исходные файлы в этом репозитории содержат полнофункциональный код, демонстрирующий использование процедуры поиска. Однако, если вы собираетесь использовать его в своем собственном коде, может быть полезно знать, какие важные фрагменты кода вам необходимо включить.
Файл | Код интереса | Стоимость интереса |
---|---|---|
*.bat | Макрос TermPid определенный в процедуре :init_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 или исключение, если произошла ошибка) |
Несколько лет назад Microsoft начала разработку нового терминального приложения — Windows Terminal. Установка доступна для Windows 10, и Windows 11 уже поставляется с ней. В обновлении, выпущенном в октябре 22 года, Microsoft превратила его в терминальное приложение по умолчанию в Windows 11.
На данный момент Windows Terminal сосуществует со старым добрым Conhost. Пользователи могут выбрать, какое из них будет использоваться в качестве терминального приложения по умолчанию.
Раньше было легко определить, какой терминальный процесс подключен к оболочному/консольному приложению. За кулисами это всегда был Conhost, и поэтому Microsoft создала Windows API, сообщавший о процессе, который породил процесс conhost, как терминальный процесс, а окно приложения оболочки сообщало как окно консоли. Хотя все это технически неправильно, но в то же время вполне комфортно.
Однако для терминала Windows такая удобная функция не реализована. А если Windows Terminal установлен в качестве терминала по умолчанию, мы не можем сделать вывод из дерева процессов, какой терминальный процесс взаимодействует с нашим процессом оболочки.
Используя Process Explorer, я заметил, что в процессе Windows Terminal открыт дескриптор процесса оболочки. Предполагая, что это всегда так, я попытался написать фрагмент кода, который перечисляет все открытые дескрипторы в поисках правильного дескриптора процесса. Для этого требуется задействовать недокументированный API. Я оставил в коде пару комментариев, которые примерно объясняют, как это все работает.
В каждом файле также есть фрагмент несвязанного кода, который затемняет и снова закрывает окно. Я нашел это впечатляющим способом доказать, что правильный процесс был найден.
Это краткое объяснение того, как реализован поиск в исходных кодах.
NtQuerySystemInformation
используется для получения снимка всех открытых дескрипторов во всех запущенных процессах. (Это официально не задокументировано.)