Поделиться через


Классические API консоли и последовательности виртуальных терминалов

Мы рекомендуем заменить классический API консоли Windowsпоследовательностью виртуальных терминалов. В этой статье будет изложена разница между двумя объектами и обсуждены причины нашей рекомендации.

Определения

Классическая область API консоли Windows определяется как ряд функциональных интерфейсов языка C, имеющих в названии слово "Console".

Последовательности виртуальных терминалов определяются как язык команд, внедренных в стандартные входные и стандартные потоки вывода. Последовательности виртуальных терминалов используют непечатаемые escape-символы для передачи сигнальных команд с обычным печатным текстом.

История

Консоль Windows предоставляет широкую область API для клиентских приложений командной строки для управления буфером вывода и буфером ввода пользователя. Однако другие платформы, отличные от Windows, никогда не предоставляли этому конкретному подходу на основе API к средам командной строки, выбирая вместо этого использовать последовательности виртуальных терминалов, внедренные в стандартные входные и стандартные выходные потоки. (В течение некоторого времени корпорация Майкрософт также поддерживала это поведение в ранних выпусках DOS и Windows с помощью драйвера, называемого ANSI.SYS.)

В отличие от этого , последовательности виртуальных терминалов (в различных диалектах) управляют операциями среды командной строки для всех других платформ. Эти последовательности коренятся в стандарте ECMA и ряде расширений от множества поставщиков, восходящих к терминалам "Digital Equipment Corporation" и "Tektronix", и доходя до более современных и распространенных программных терминалов, таких как xterm. Многие расширения существуют в домене последовательности виртуальных терминалов, и некоторые последовательности более широко поддерживаются, чем другие, но безопасно сказать, что мир стандартизировал этот язык в качестве языка команд для интерфейса командной строки с хорошо известным подмножеством, поддерживаемым практически каждым клиентским приложением терминала и командной строки.

Кроссплатформенная поддержка

Последовательности виртуальных терминалов изначально поддерживаются на разных платформах, что делает приложения терминалов и служебные программы командной строки легко переносимыми между версиями и вариантами операционных систем, за исключением Windows.

В отличие от этого , API консоли Windows поддерживаются только в Windows. Обширная библиотека адаптера или перевода должна быть записана между Windows и виртуальным терминалом или наоборот, при попытке перенести служебные программы командной строки с одной или другой платформы.

Удаленный доступ

Последовательности виртуальных терминалов имеют основное преимущество для удаленного доступа. Им не требуется дополнительной работы для передачи или выполнения удалённых вызовов процедур по сравнению с тем, что необходимо для настройки стандартного подключения к удаленной командной строке. Простое подключение исходящего и входящего транспортного канала (или одного двунаправленного канала) по каналу, сокету, файлу, последовательному порту или любому другому устройству достаточно, чтобы полностью перенести все сведения, необходимые для приложения, говоря эти последовательности удаленному узлу.

Однако API консоли Windows доступны только на локальном компьютере, и все усилия по их удаленному доступу или управлению потребуют создания целого слоя удаленного вызова и транспортного интерфейса, в отличие от простого канала.

Разделение задач

Некоторые API консоли Windows предоставляют низкоуровневый доступ к входным и выходным буферам или удобные функции для интерактивных команд. Это может включать псевдонимы и журнал команд, программируемые в подсистеме консоли и среде узла, а не в самом клиентском приложении командной строки.

В отличие от других платформ, которые возлагают ответственность за запоминание текущего состояния приложения и функционалов удобства на служебные программы командной строки или оболочку.

Способ обработки этой ответственности в узле консоли и API позволяет быстрее и проще писать приложение командной строки с этими функциями, удаляя ответственность за запоминание состояния рисования или обработку удобных функций редактирования. Однако это делает практически невозможным удаленное подключение этих действий на разных платформах, версиях или сценариях из-за вариантов реализации и доступности. Этот способ управления ответственностью также делает итоговый интерактивный опыт этих приложений командной строки Windows полностью зависимым от реализации, приоритетов и цикла выпуска консольного хоста.

Например, расширенные функции редактирования строк, такие как выделение синтаксиса и сложный выбор, возможны только в том случае, если приложение командной строки обрабатывает проблемы редактирования. Консоль никогда не может иметь достаточно контекста, чтобы полностью понять эти сценарии столь же полно, как это делает клиентское приложение.

В отличие от этого, другие платформы используют последовательности виртуальных терминалов для обработки этих действий и взаимодействия виртуальных терминалов с помощью клиентских библиотек, предназначенных для многократного использования, таких как readline и ncurses. Окончательный терминал отвечает только за отображение информации и получение входных данных через этот двунаправленный канал связи.

глаголы Wrong-Way

С помощью консоли Windows некоторые действия можно выполнять в противоположном естественном направлении для входных и выходных потоков. Это позволяет приложениям командной строки Windows избежать проблем управления собственными буферами. Он также позволяет приложениям командной строки Windows выполнять расширенные операции, такие как имитация и инъекция входных данных от имени пользователя или чтение истории некоторых вводов.

Хотя это обеспечивает дополнительную мощность для приложений Windows, работающих в определенном контексте пользователя на одном компьютере, он также предоставляет вектор для пересечения уровней безопасности и привилегий или доменов при использовании в определенных сценариях. Такие сценарии включают работу между контекстами на одном компьютере или между контекстами в другой машине или среде.

Другие платформы, использующие последовательности виртуальных терминалов, не разрешают это действие. Наша рекомендация по переходу с классической консоли Windows на последовательности виртуальных терминалов заключается в том, чтобы объединиться с этой стратегией как по соображениям взаимодействия, так и по соображениям безопасности.

Прямой доступ к окну

Поверхность API консоли Windows предоставляет точный идентификатор окна для окна размещения. Это позволяет утилите командной строки выполнять расширенные операции с окном, обращаясь к широкому спектру API Win32, разрешенных для работы с дескриптором окна. Эти API Win32 могут управлять состоянием окна, кадром, значком или другими свойствами в окне.

В отличие от этого, на других платформах с последовательностями виртуальных терминалов существует узкий набор команд, которые можно выполнить в окне. Эти команды могут выполнять такие действия, как изменение размера окна или отображаемого заголовка, но они должны выполняться в том же диапазоне и под тем же элементом управления, что и остальная часть потока.

По мере развития Windows увеличились средства управления безопасностью и ограничения для дескрипторов окон. Кроме того, характер и существование дескриптора окна, доступного для приложений, на любом определенном элементе пользовательского интерфейса развивались, особенно с повышенной поддержкой форм-факторов и платформ устройств. Это делает прямой доступ к приложениям командной строки хрупким по мере развития платформы и возможностей.

Юникод

UTF-8 — это приемлемая кодировка для данных Юникода почти на всех современных платформах, так как она обеспечивает правильный баланс между переносимостью, размером хранилища и временем обработки. Тем не менее, Windows исторически выбрал UTF-16 в качестве основной кодировки для данных Юникода. Поддержка UTF-8 увеличивается в Windows и использование этих форматов Юникода не исключает использование других кодировк.

Платформа консоли Windows поддерживается и будет продолжать поддерживать все существующие кодовые страницы и кодировки. При необходимости используйте UTF-16 для обеспечения максимальной совместимости между версиями Windows и выполнения алгоритмического перевода с UTF-8. Увеличение поддержки UTF-8 выполняется для консольной системы.

Поддержка UTF-16 в консоли может использоваться без дополнительной настройки с помощью варианта W всех API консоли и является более вероятным выбором для приложений, уже хорошо работающих с UTF-16 посредством взаимодействия с другими функциями и продуктами платформы Microsoft и Windows в вариантах wchar_t и W.

Поддержку UTF-8 в консоли можно использовать через вариант A API консоли для дескрипторов консоли после установки кодовой страницы на 65001 или CP_UTF8 с помощью методов SetConsoleOutputCP и SetConsoleCP в соответствии с необходимостью. Заранее задать кодовые страницы необходимо, только если компьютер не выбрал параметр "Использовать UTF-8 Юникода для поддержки языка по всему миру" в параметрах приложений, отличных от Юникода, в разделе "Регион" панели управления.

Замечание

По состоянию на данный момент UTF-8 полностью поддерживается в стандартном выходном потоке с помощью методов WriteConsole и WriteFile . Поддержка входного потока зависит от режима ввода и продолжает улучшаться с течением времени. В частности, режимы ввода по умолчанию "приготовлены" пока не поддерживают UTF-8. Текущее состояние этой работы можно найти в microsoft/terminal#7777 на сайте GitHub. Решением является использование алгоритмически переводимого UTF-16 для чтения входных данных с помощью ReadConsoleW или ReadConsoleInputW , пока не будут устранены невыполненные проблемы.

Рекомендации

Для всех новых и текущих разработок в Windows рекомендуется использовать последовательности виртуальных терминалов в качестве способа взаимодействия с терминалом. Это приведет к конвергентным клиентским приложениям командной строки Windows с стилем программирования приложений на всех других платформах.

Исключения для использования API консоли Windows

Ограниченное подмножество API консоли Windows по-прежнему необходимо для установки начальной среды. Платформа Windows по-прежнему отличается от других в процессе, сигнале, устройстве и обработке кодирования:

  • Стандартные дескрипторы процесса по-прежнему будут управляться функциями GetStdHandle и SetStdHandle.

  • Настройка режимов консоли в дескрипторе для поддержки последовательности виртуальных терминалов осуществляется с помощью GetConsoleMode и SetConsoleMode.

  • Объявление кодовой страницы или поддержки UTF-8 проводится с методами SetConsoleOutputCP и SetConsoleCP .

  • Некоторый уровень общего управления процессами может потребоваться с AllocConsole, AttachConsole и FreeConsole для присоединения или выхода из сеанса устройства консоли.

  • Сигналы и обработка сигналов будут и дальше осуществляться с SetConsoleCtrlHandler, HandlerRoutine и GenerateConsoleCtrlEvent.

  • Взаимодействие с дескрипторами консольного устройства осуществляется с помощью WriteConsole и ReadConsole. Они также могут использоваться с помощью сред выполнения языка программирования в формах: — C Runtime (CRT): Stream I/O, например printf, scanf, putc, getc или других уровней функций ввода-вывода. — Стандартная библиотека C++ (STL): iostream , например coutи cin. — среда выполнения .NET: System.Console , например Console.WriteLine.

  • Приложения, которые должны учитывать изменения размера окна, по-прежнему должны использовать ReadConsoleInput для их переключения с ключевыми событиями, так как Только ReadConsole отбрасывает их.

  • Для поиска размера окна всё ещё необходимо использовать GetConsoleScreenBufferInfo для приложений, пытающихся нарисовать столбцы, сетку или заполнить отображение. Размер окна и буфера будет соответствовать в сеансе псевдоконсоли.

Планирование будущего и псевдоконсоли

Нет планов удалить API консоли Windows с платформы.

Напротив, хост консоли Windows предоставил технологию псевдоконсоли для перевода существующих вызовов приложений командной строки Windows в последовательности виртуальных терминалов и перенаправляет их в другую хостинговую среду удалённо или на разные платформы.

Этот перевод не является идеальным. Для этого требуется окно консольного хоста для поддержания имитированной среды, которую Windows отображал бы пользователю. Затем он проектирует реплику этой имитированной среды на псевдоконсоль хост. Все вызовы API консоли Windows выполняются в имитированной среде для обслуживания потребностей устаревшего клиентского приложения командной строки. Только эффекты распространяются на конечный узел.

Поэтому приложению командной строки, стремящемуся к полной совместимости между платформами и поддержке всех новых функций и сценариев как на Windows, так и на других платформах, рекомендуется перейти на использование последовательностей виртуальных терминалов и адаптировать архитектуру приложений командной строки для соответствия всем платформам.

Дополнительные сведения об этом переходе Windows для приложений командной строки см. в нашей стратегии развития экосистемы.