IMPORTANTE
O novo modelo de processo do Windows Terminal versão 1.18 requer uma abordagem diferente.
Consulte https://github.com/german-one/termwnd para a nova implementação.
O objetivo do código neste repositório é distinguir entre os processos Conhost e Terminal do Windows e determinar qual instância de terminal está conectada ao processo do console atual. Aplicativos de terminal de terceiros não são suportados.
Os arquivos de origem são transcrições praticamente do mesmo código principal em diferentes linguagens de programação.
Os arquivos de origem em Windows Batch
, C
, C++
, C#.Net
, PowerShell
e VB.Net
são publicados na pasta src. Todos eles dependem do Windows ser o sistema operacional de destino. Outras dependências específicas estão listadas abaixo.
Arquivo | Exigência |
---|---|
*.bat | Windows PowerShell 2 |
*.c | Capítulo 99 |
*.cpp | C++20 |
*.cs | .NET Framework 4.5 |
*.ps1 | Windows PowerShell 2 |
*.vb | .NET Framework 4.5 |
Os arquivos fonte neste repositório contêm código totalmente funcional que demonstra como usar o procedimento de pesquisa. No entanto, se você pretende usá-lo em seu próprio código, pode ser útil saber quais partes essenciais do código você precisa incluir.
Arquivo | Código de interesse | Valor de interesse |
---|---|---|
*.bat | Macro TermPid definida na rotina :init_TermPid | o errorlevel retornado pela macro TermPid é o PID do terminal de hospedagem ( 0 se ocorreu um erro) |
*.c | Função GetTermPid , junto com a estrutura SYSTEM_HANDLE e funções GetProcBaseName , GetPidOfNamedProcWithOpenProcHandle | o valor retornado pela função GetTermPid é o PID do terminal de hospedagem ( 0 se ocorreu um erro) |
*.cpp | tudo no namespace termpid , junto com namespace saferes e a função GetProcBaseName | o valor retornado pela função GetTermPid é o PID do terminal de hospedagem ( 0 ou exceção se ocorreu um erro) |
*.cs | classe WinTerm | o valor da propriedade WinTerm.TermProc refere-se ao processo do terminal de hospedagem ( null ou exceção se ocorreu um erro) |
*.ps1 | Classe de referência de tipo WinTerm | o valor da propriedade [WinTerm]::TermProc refere-se ao processo do terminal de hospedagem ( $null ou tipo WinTerm não definido se ocorreu um erro) |
*.vb | Módulo WinTerm | o valor da propriedade WinTerm.TermProc refere-se ao processo do terminal de hospedagem ( Nothing ou exceção se ocorreu um erro) |
Há alguns anos, a Microsoft começou a desenvolver um novo aplicativo de terminal - Windows Terminal. A instalação está disponível para Windows 10 e o Windows 11 já vem com ela. Por meio de uma atualização em 22 de outubro, a Microsoft o transformou no aplicativo de terminal padrão no Windows 11.
A partir de agora, o Windows Terminal coexiste com o bom e velho Conhost. Os usuários podem escolher qual será o aplicativo de terminal padrão.
No passado, era fácil descobrir qual processo de terminal estava conectado ao aplicativo shell/console. Nos bastidores sempre foi o Conhost e, portanto, a Microsoft fez a API do Windows relatar o processo que gerou o processo conhost como o processo do terminal e relatar a janela do aplicativo shell como a janela do console. Embora tudo isso seja tecnicamente incorreto, é bastante confortável ao mesmo tempo.
No entanto, nenhuma funcionalidade de conveniência é implementada para o Terminal Windows. E se o Terminal do Windows estiver definido como terminal padrão, não podemos inferir da árvore de processos qual processo de terminal está se comunicando com nosso processo shell.
Usando o Process Explorer, observei que o processo do Terminal do Windows possui um identificador para o processo do shell aberto. Supondo que esse seja sempre o caso, tentei escrever um trecho de código que enumera todos os identificadores abertos procurando o identificador de processo correto. Isso requer o envolvimento de alguma API não documentada. Deixei alguns comentários no código que explicam aproximadamente como tudo isso funciona.
Em cada arquivo há também um pedaço de código não relacionado que faz com que a janela apareça e apareça novamente. Achei uma forma impressionante de provar que o processo certo foi encontrado.
Esta é uma breve explicação de como a pesquisa é implementada nos códigos-fonte.
NtQuerySystemInformation
é usada para obter um instantâneo de todos os identificadores abertos em todos os processos em execução. (Isso não está oficialmente documentado.)