Partilhar via


APIs de console clássicas versus sequências de terminal virtual

Nossa recomendação é substituir a API clássica do Console do Windows por sequências de terminais virtuais. Este artigo irá descrever a diferença entre os dois e discutir as razões para a nossa recomendação.

Definições

A superfície clássica da API do Console do Windows é definida como a série de interfaces funcionais da linguagem C com kernel32.dll "Console" no nome.

As sequências de terminais virtuais são definidas como uma linguagem de comandos incorporada nos fluxos de entrada e saída padrão. As sequências de terminais virtuais usam caracteres de escape não imprimíveis para comandos de sinalização intercalados com texto normal imprimível.

História

O Console do Windows fornece uma ampla superfície de API para que os aplicativos de linha de comando cliente manipulem o buffer de exibição de saída e o buffer de entrada do usuário. No entanto, outras plataformas que não são do Windows nunca ofereceram essa abordagem específica orientada por API para seus ambientes de linha de comando, optando por usar sequências de terminais virtuais incorporadas nos fluxos de entrada e saída padrão padrão. (Por um tempo, a Microsoft também deu suporte a esse comportamento nas primeiras edições do DOS e do Windows por meio de um driver chamado ANSI.SYS.)

Por outro lado, sequências de terminais virtuais (em uma variedade de dialetos) conduzem as operações do ambiente de linha de comando para todas as outras plataformas. Essas sequências estão enraizadas em um padrão ECMA e em uma série de extensões de muitos fornecedores que remontam aos terminais Digital Equipment Corporation e Tektronix, até terminais de software mais modernos e comuns, como o xterm. Muitas extensões existem dentro do domínio de sequência de terminal virtual e algumas sequências são mais amplamente suportadas do que outras, mas é seguro dizer que o mundo padronizou isso como a linguagem de comando para experiências de linha de comando com um subconjunto bem conhecido sendo suportado por praticamente todos os terminais e aplicativos cliente de linha de comando.

Suporte entre plataformas

As sequências de terminais virtuais são suportadas nativamente em todas as plataformas, tornando os aplicativos de terminal e utilitários de linha de comando facilmente portáteis entre versões e variações de sistemas operacionais, com exceção do Windows.

Por outro lado, as APIs do Console do Windows só são suportadas no Windows. Um adaptador extenso ou biblioteca de tradução deve ser escrito entre o Windows e o terminal virtual, ou vice-versa, ao tentar portar utilitários de linha de comando de uma plataforma ou outra.

Acesso Remoto

As sequências de terminais virtuais têm uma grande vantagem para o acesso remoto. Eles não requerem trabalho adicional para transportar ou realizar chamadas de procedimento remoto além do necessário para configurar uma conexão padrão de linha de comando remota. Basta conectar um canal de transporte de saída e de entrada (ou um único canal bidirecional) através de um tubo, soquete, arquivo, porta serial ou qualquer outro dispositivo para transportar completamente todas as informações necessárias para um aplicativo que transmite essas sequências a um host remoto.

Pelo contrário, as APIs do Console do Windows só foram acessíveis na máquina local e todos os esforços para controlá-las remotamente exigiriam a criação de uma camada inteira de interface de transporte e chamada remota além de apenas um simples canal.

Separação de preocupações

Algumas APIs do Console do Windows fornecem acesso de baixo nível aos buffers de entrada e saída ou funções de conveniência para linhas de comando interativas. Isso pode incluir aliases e histórico de comandos programados no subsistema do console e no ambiente do host, em vez de dentro do próprio aplicativo cliente de linha de comando.

Por outro lado, outras plataformas tornam a memória do estado atual do aplicativo e a funcionalidade de conveniência responsabilidade do utilitário de linha de comando ou do próprio shell.

A forma como o Console do Windows lida com essa responsabilidade no host e na API do console torna mais rápido e fácil escrever uma aplicação de linha de comando com essas funcionalidades, eliminando a necessidade de se lembrar do estado do desenho ou de gerir funcionalidades de edição convenientes. No entanto, isso torna quase impossível conectar essas atividades remotamente entre plataformas, versões ou cenários devido a variações nas implementações e disponibilidade. Essa maneira de lidar com a responsabilidade também torna a experiência interativa final desses aplicativos de linha de comando do Windows completamente dependente da implementação, prioridades e ciclo de lançamento do host do console.

Por exemplo, recursos avançados de edição de linha, como realce de sintaxe e seleção complexa, só são possíveis quando um aplicativo de linha de comando lida com questões de edição. O console nunca poderia ter contexto suficiente para entender completamente esses cenários de uma maneira ampla, como o aplicativo cliente pode.

Por outro lado, outras plataformas usam sequências de terminais virtuais para lidar com essas atividades e a própria comunicação do terminal virtual por meio de bibliotecas reutilizáveis do lado do cliente, como readline e ncurses. O terminal final é responsável apenas por exibir informações e receber informações através desse canal de comunicação bidirecional.

Wrong-Way Verbos

Com o Console do Windows, algumas ações podem ser executadas na direção oposta ao natural nos fluxos de entrada e saída. Isso permite que os aplicativos de linha de comando do Windows evitem a preocupação de gerenciar seus próprios buffers. Ele também permite que os aplicativos de linha de comando do Windows executem operações avançadas, como simular/injetar entrada em nome de um usuário ou ler parte do histórico do que foi escrito.

Embora isso forneça poder adicional para aplicativos do Windows que operam em um contexto de usuário específico em uma única máquina, ele também fornece um vetor para cruzar segurança e níveis de privilégio ou domínios quando usado em determinados cenários. Esses cenários incluem a operação entre contextos na mesma máquina ou entre contextos para outra máquina ou ambiente.

Outras plataformas, que utilizam sequências de terminais virtuais, não permitem esta atividade. A intenção da nossa recomendação de fazer a transição do Console clássico do Windows para as sequências de terminais virtuais é convergir com essa estratégia por motivos de interoperabilidade e segurança.

Acesso direto à janela

A superfície da API do Console do Windows fornece o identificador de janela exato para a janela de hospedagem. Isso permite que um utilitário de linha de comando execute operações avançadas de janela, alcançando a ampla gama de APIs do Win32 permitidas em relação a um identificador de janela. Essas APIs do Win32 podem manipular o estado da janela, quadro, ícone ou outras propriedades sobre a janela.

Por outro lado, em outras plataformas com sequências de terminais virtuais, há um conjunto estreito de comandos que podem ser executados contra a janela. Esses comandos podem fazer coisas como alterar o tamanho da janela ou o título exibido, mas devem ser feitos na mesma banda e sob o mesmo controle que o restante do fluxo.

À medida que o Windows evoluiu, os controles de segurança e as restrições nas alças das janelas aumentaram. Além disso, a natureza e a existência de um identificador de janela acessível pelo aplicativo em qualquer elemento específico da interface do usuário evoluiu, especialmente com o suporte crescente a formatos e plataformas de dispositivos. Isso torna o acesso direto à janela para aplicativos de linha de comando frágil à medida que a plataforma e as experiências evoluem.

Unicode

UTF-8 é a codificação aceita para dados Unicode em quase todas as plataformas modernas, pois atinge o equilíbrio certo entre portabilidade, tamanho de armazenamento e tempo de processamento. No entanto, o Windows historicamente escolheu UTF-16 como sua codificação principal para dados Unicode. O suporte para UTF-8 está aumentando no Windows e o uso desses formatos Unicode não impede o uso de outras codificações.

A plataforma de Consola Windows tem suportado e continuará a suportar todas as páginas de código e codificações existentes. Use UTF-16 para máxima compatibilidade entre versões do Windows e execute a tradução algorítmica com UTF-8, se necessário. Aumento do suporte a UTF-8 está em curso para o sistema de consola.

O suporte a UTF-16 no console pode ser utilizado sem configuração adicional através da variante W de todas as APIs do console e é uma escolha mais provável para aplicativos já bem versados em UTF-16 através da comunicação com a wchar_t variante e W de outras funções e produtos da plataforma Microsoft e Windows.

O suporte a UTF-8 no console pode ser utilizado por meio da variante A de APIs de console contra identificadores de console depois de definir a página de código para 65001 ou CP_UTF8 com os métodos SetConsoleOutputCP e SetConsoleCP , conforme apropriado. Definir as páginas de código com antecedência só é necessário se a máquina não tiver escolhido "Usar Unicode UTF-8 para suporte a idiomas em todo o mundo" nas configurações para aplicativos não-Unicode na seção Região do Painel de Controle.

Observação

A partir de agora, UTF-8 é suportado totalmente no fluxo de saída padrão com os métodos WriteConsole e WriteFile . O suporte no fluxo de entrada varia dependendo do modo de entrada e continuará a melhorar ao longo do tempo. Notavelmente, os modos "cozidos" padrão na entrada ainda não suportam totalmente UTF-8. O status atual deste trabalho pode ser encontrado em microsoft/terminal#7777 no GitHub. A solução alternativa é usar o UTF-16 traduzível por algoritmo para ler a entrada através de ReadConsoleW ou ReadConsoleInputW até que os problemas pendentes sejam resolvidos.

Recomendações

Para todo o desenvolvimento novo e contínuo no Windows, as sequências de terminais virtuais são recomendadas como forma de interagir com o terminal. Isso convergirá os aplicativos cliente de linha de comando do Windows com o estilo de programação de aplicativos em todas as outras plataformas.

Exceções para usar APIs do Console do Windows

Um subconjunto limitado de APIs do Console do Windows ainda é necessário para estabelecer o ambiente inicial. A plataforma Windows ainda difere de outras no processamento de processos, sinal, dispositivo e codificação:

Planeamento futuro e pseudoconsola

Não há planos para remover as APIs do console do Windows da plataforma.

Pelo contrário, o host do Console do Windows forneceu a tecnologia de pseudoconsole para traduzir chamadas de aplicativos de linha de comando existentes do Windows em sequências de terminais virtuais e encaminhá-las para outro ambiente de hospedagem remotamente ou entre plataformas.

Esta tradução não é perfeita. Ele requer que a janela do host do console mantenha um ambiente simulado do que o Windows teria exibido para o usuário. Em seguida, ele projeta uma réplica desse ambiente simulado para o host do pseudoconsole . Todas as chamadas de API do Console Windows são operadas dentro do ambiente simulado para atender às necessidades do aplicativo cliente de linha de comando herdado. Apenas os efeitos são propagados para o hospedeiro final.

Um aplicativo de linha de comando desejando total compatibilidade entre plataformas e suporte total de todos os novos recursos e cenários, tanto no Windows quanto em outros lugares, é, portanto, recomendado para mover para sequências de terminal virtual e ajustar a arquitetura de aplicativos de linha de comando para alinhar com todas as plataformas.

Mais informações sobre essa transição do Windows para aplicativos de linha de comando podem ser encontradas em nosso roteiro de ecossistema.