Partager via


API de console classique et séquences de terminal virtuel

Nous vous recommandons de remplacer l’API de console Windows classique par des séquences de terminal virtuel. Cet article décrit la différence entre les deux et discutera des raisons de notre recommandation.

Définitions

La surface de l’API de console Windows classique est définie comme la série d’interfaces fonctionnelles du langage C sur kernel32.dll dont le nom contient « Console ».

Les séquences de terminal virtuel sont définies en tant que langage de commandes incorporées dans les flux d’entrée et de sortie standard. Les séquences de terminal virtuel utilisent des caractères d’échappement non imprimables pour signaler des commandes entrelacées avec du texte imprimable normal.

Histoire

La console Windows fournit une grande surface d’API pour les applications de ligne de commande clientes afin de manipuler à la fois la mémoire tampon d’affichage de sortie et la mémoire tampon d’entrée utilisateur. Toutefois, d’autres plateformes non-Windows n’ont jamais accordé cette approche basée sur l’API spécifique à leurs environnements de ligne de commande, en choisissant plutôt d’utiliser des séquences de terminal virtuel incorporées dans les flux de sortie standard et d’entrée standard. (Pendant un certain temps, Microsoft a également supporté ce comportement dans les premières éditions de DOS et Windows par le biais d’un pilote appelé ANSI.SYS.)

En revanche, les séquences de terminal virtuel (dans un large éventail de dialectes) pilotent les opérations d’environnement de ligne de commande pour toutes les autres plateformes. Ces séquences sont enracinées dans une norme ECMA et une série d’extensions par de nombreux fournisseurs retraçant les terminaux Digital Equipment Corporation et Tektronix, jusqu’à des terminaux logiciels plus modernes et courants, comme xterm. De nombreuses extensions existent dans le domaine de séquence de terminal virtuel et certaines séquences sont plus largement prises en charge que d’autres, mais il est sûr de dire que le monde a normalisé cela comme langage de commande pour les expériences de ligne de commande avec un sous-ensemble bien connu pris en charge par pratiquement chaque application cliente de terminal et de ligne de commande.

Prise en charge multiplateforme

Les séquences de terminal virtuel sont prises en charge en mode natif sur plusieurs plateformes, ce qui rend les applications terminales et les utilitaires de ligne de commande facilement portables entre les versions et les variantes des systèmes d’exploitation, à l’exception de Windows.

En revanche, les API de console Windows ne sont prises en charge que sur Windows. Une bibliothèque complète d’adaptateurs ou de traductions doit être écrite entre Windows et le terminal virtuel, ou vice versa, lors d’une tentative de port d’utilitaires de ligne de commande à partir d’une plateforme ou d’une autre.

Accès à distance

Les séquences de terminal virtuel présentent un avantage majeur pour l’accès à distance. Ils ne nécessitent pas de travail supplémentaire pour le transfert ni pour effectuer des appels de procédure à distance par rapport à ce qui est nécessaire pour configurer une connexion standard de ligne de commande à distance. Il suffit de connecter un canal de transport sortant et entrant (ou un seul canal bidirectionnel) sur un tuyau, un socket, un fichier, un port série ou tout autre appareil pour transporter intégralement toutes les informations requises pour une application transmettant ces séquences à un hôte distant.

Au contraire, les API console Windows n’ont été accessibles que sur l’ordinateur local et tous les efforts déployés pour les distancer nécessitent la création d’une couche d’interface d’appel à distance et de transport entière au-delà d’un canal simple.

Séparation des responsabilités

Certaines API de console Windows fournissent un accès de bas niveau aux mémoires tampons d’entrée et de sortie ou aux fonctions pratiques pour les lignes de commande interactives. Cela peut inclure des alias et l’historique des commandes programmés dans le sous-système de console et l’environnement hôte, au lieu de l’application cliente de ligne de commande elle-même.

En revanche, d’autres plateformes font de la mémoire de l’état actuel de l’application et des fonctionnalités pratiques la responsabilité de l’utilitaire de ligne de commande ou de l’interpréteur de commandes lui-même.

La façon de gérer cette responsabilité dans l’hôte et l’API de la console permet d’écrire plus rapidement et plus facilement une application en ligne de commande avec ces fonctionnalités, en supprimant la responsabilité de mémoriser l’état du dessin ou de gérer les fonctionnalités pratiques d’édition. Toutefois, cela rend presque impossible la connexion de ces activités à distance entre plateformes, versions ou scénarios en raison de variations d’implémentations et de disponibilité. Cette façon de gérer la responsabilité rend également l’expérience interactive finale de ces applications en ligne de commande Windows entièrement dépendante de l’implémentation, des priorités et du cycle de mise en production de l’hôte de console.

Par exemple, les fonctionnalités avancées de modification de ligne, telles que la mise en surbrillance de la syntaxe et la sélection complexe, ne sont possibles que lorsqu’une application en ligne de commande gère les problèmes d’édition lui-même. La console ne pouvait jamais avoir suffisamment de contexte pour comprendre pleinement ces scénarios de manière générale, comme l’application cliente.

En revanche, d’autres plateformes utilisent des séquences de terminal virtuel pour gérer ces activités et la communication de terminal virtuel elle-même via des bibliothèques côté client réutilisables, telles que readline et ncurses. Le terminal final est uniquement responsable de l’affichage des informations et de la réception d’entrée via ce canal de communication bidirectionnel.

Verbes à direction inverse

Avec la console Windows, certaines actions peuvent être effectuées dans la direction opposée à naturelle sur les flux d’entrée et de sortie. Cela permet aux applications de ligne de commande Windows d’éviter le souci de gérer leurs propres mémoires tampons. Il permet également aux applications de ligne de commande Windows d’effectuer des opérations avancées, telles que la simulation/l’injection d’entrée pour le compte d’un utilisateur, ou la lecture de l’historique de ce qui a été écrit.

Bien que cela offre une puissance supplémentaire aux applications Windows fonctionnant dans un contexte utilisateur spécifique sur un seul ordinateur, il fournit également un vecteur pour traverser les niveaux de sécurité et de privilèges ou les domaines lorsqu’ils sont utilisés dans certains scénarios. Ces scénarios incluent le fonctionnement entre des contextes sur le même ordinateur ou entre des contextes vers un autre ordinateur ou un autre environnement.

D’autres plateformes, qui utilisent des séquences de terminal virtuel, n’autorisent pas cette activité. L’objectif de notre recommandation de passer de la console Windows classique aux séquences de terminal virtuel consiste à converger avec cette stratégie pour des raisons d’interopérabilité et de sécurité.

Accès direct à la fenêtre

La surface de l’API de console Windows fournit le poignée de fenêtre exact vers la fenêtre d’hébergement. Cela permet à un utilitaire de ligne de commande d’effectuer des opérations de fenêtre avancées en atteignant la gamme étendue des API Win32 autorisées par rapport à un handle de fenêtre. Ces API Win32 peuvent manipuler l’état de la fenêtre, le cadre, l’icône ou d’autres propriétés sur la fenêtre.

En revanche, sur d’autres plateformes avec des séquences de terminal virtuel, il existe un ensemble étroit de commandes qui peuvent être effectuées sur la fenêtre. Ces commandes peuvent effectuer des opérations telles que la modification de la taille de la fenêtre ou du titre affiché, mais elles doivent être effectuées dans la même bande et sous le même contrôle que le reste du flux.

À mesure que Windows a évolué, les contrôles de sécurité et les restrictions sur les poignées de fenêtre ont augmenté. En outre, la nature et l’existence d’une poignée de fenêtre adressable par l’application sur un élément spécifique de l’interface utilisateur ont évolué, en particulier avec la prise en charge accrue des formats d’appareils et des plateformes. Cela rend l’accès direct aux applications en ligne de commande fragiles à mesure que la plateforme et les expériences évoluent.

Unicode

UTF-8 est l’encodage accepté pour les données Unicode sur presque toutes les plateformes modernes, car il atteint le bon équilibre entre la portabilité, la taille de stockage et le temps de traitement. Toutefois, Windows a choisi historiquement UTF-16 comme encodage principal pour les données Unicode. La prise en charge de UTF-8 augmente dans Windows et l’utilisation de ces formats Unicode n’empêche pas l’utilisation d’autres encodages.

La plateforme console Windows a pris en charge et continuera de prendre en charge toutes les pages de code et encodages existants. Utilisez UTF-16 pour une compatibilité maximale entre les versions de Windows et effectuez une traduction algorithmique avec UTF-8 si nécessaire. L’augmentation de la prise en charge de UTF-8 est en cours pour le système de console.

La prise en charge UTF-16 dans la console peut être utilisée sans configuration supplémentaire via la variante W de toutes les API de console et est un choix plus probable pour les applications déjà bien familiarisées dans UTF-16 via la communication avec la wchar_t variante W d’autres fonctions et produits de plateforme Microsoft et Windows.

La prise en charge de UTF-8 dans la console peut être utilisée via la variante A des API console pour les handles de console après avoir défini la page de codes sur 65001 ou CP_UTF8 avec les méthodes SetConsoleOutputCP et SetConsoleCP, le cas échéant. La définition des pages de codes à l’avance n’est nécessaire que si l’ordinateur n’a pas choisi « Utiliser Unicode UTF-8 pour la prise en charge linguistique mondiale » dans les paramètres des applications non Unicode dans la section Région du Panneau de configuration.

Remarque

À l’heure actuelle, UTF-8 est entièrement pris en charge sur le flux de sortie standard avec les méthodes WriteConsole et WriteFile . La prise en charge du flux d’entrée varie en fonction du mode d’entrée et continuera à s’améliorer au fil du temps. Notamment les modes « cuits » par défaut sur l’entrée ne prennent pas entièrement en charge UTF-8. L’état actuel de ce travail se trouve sur microsoft/terminal#7777 sur GitHub. La solution de contournement consiste à utiliser l’UTF-16 algorithmique pour lire l’entrée via ReadConsoleW ou ReadConsoleInputW jusqu’à ce que les problèmes en suspens soient résolus.

Recommandations

Pour tous les nouveaux développements et en cours sur Windows, les séquences de terminal virtuel sont recommandées comme moyen d’interagir avec le terminal. Cela harmonisera les applications clientes de ligne de commande sous Windows avec le style de programmation d'applications sur toutes les autres plateformes.

Exceptions pour l’utilisation des API de console Windows

Un sous-ensemble limité d’API de console Windows est toujours nécessaire pour établir l’environnement initial. La plateforme Windows diffère toujours des autres dans le processus, le signal, l’appareil et la gestion de l’encodage :

  • Les handles standard d’un processus seront toujours contrôlés avec GetStdHandle et SetStdHandle.

  • La configuration des modes de console sur un handle afin d’adopter la prise en charge des séquences de terminaux virtuels sera gérée avec GetConsoleMode et SetConsoleMode.

  • La déclaration de la page de codes ou de la prise en charge UTF-8 est effectuée avec les méthodes SetConsoleOutputCP et SetConsoleCP .

  • Certains niveaux de gestion globale des processus peuvent être requis avec allocConsole, AttachConsole et FreeConsole pour joindre ou quitter une session d’appareil console.

  • La gestion des signaux continuera d’être effectuée avec SetConsoleCtrlHandler, HandlerRoutine et GenerateConsoleCtrlEvent.

  • La communication avec les handles d’appareil de console peut être effectuée avec WriteConsole et ReadConsole. Elles peuvent également être exploitées par le biais d'environnements d'exécution de langage de programmation comme suit : - C Runtime (CRT) : E/S de flux comme printf, scanf, putc, getc ou d'autres niveaux de fonctions d'entrée/sortie. - Bibliothèque standard C++ (STL) : iostream comme cout et cin. - Runtime .NET : System.Console comme Console.WriteLine.

  • Les applications qui doivent connaître les modifications de taille de fenêtre devront toujours utiliser ReadConsoleInput pour les recevoir entrelacées avec les événements clés, car ReadConsole seul les ignorera.

  • La recherche de la taille de la fenêtre doit toujours être effectuée avec GetConsoleScreenBufferInfo pour les applications qui tentent de dessiner des colonnes, des grilles ou de remplir l’affichage. La taille de la fenêtre et celle de la mémoire tampon correspondront dans une session de pseudoconsole.

Planification future et pseudoconsole

Il n’existe aucun plan pour supprimer les API de console Windows de la plateforme.

Au contraire, l’hôte de la console Windows a fourni la technologie pseudoconsole pour traduire les appels d’application de ligne de commande Windows existants en séquences de terminal virtuel et les transférer vers un autre environnement d’hébergement à distance ou sur plusieurs plateformes.

Cette traduction n’est pas parfaite. Il nécessite que la fenêtre hôte de la console conserve un environnement simulé de ce que Windows aurait affiché à l’utilisateur. Il projette ensuite une réplique de cet environnement simulé à l’hôte pseudoconsole. Tous les appels d’API console Windows sont gérés dans l’environnement simulé pour répondre aux besoins de l’application cliente de ligne de commande héritée. Seuls les effets sont propagés sur l’hôte final.

Une application de ligne de commande souhaitant une compatibilité complète entre les plateformes et une prise en charge complète de toutes les nouvelles fonctionnalités et scénarios sur Windows et ailleurs est donc recommandée pour passer aux séquences de terminal virtuel et ajuster l’architecture des applications en ligne de commande pour s’aligner sur toutes les plateformes.

Vous trouverez plus d’informations sur cette transition Windows pour les applications en ligne de commande dans notre feuille de route de l’écosystème.