Udostępnij przez


Klasyczne API konsoli vs sekwencje terminali wirtualnych

Naszym zaleceniem jest zastąpienie klasycznego interfejsu API konsoli systemu Windowssekwencjami terminali wirtualnych. W tym artykule opisano różnicę między nimi i omówimy przyczyny naszej rekomendacji.

Definicje

Klasyczna powierzchnia interfejsu API konsoli systemu Windows jest definiowana jako seria interfejsów funkcjonalnych języka C z kernel32.dll nazwą "Konsola".

Wirtualne sekwencje terminali są definiowane jako język poleceń osadzonych w standardowych strumieniach wejściowych i standardowych danych wyjściowych. Wirtualne sekwencje terminali używają niedrukowalnych znaków ucieczki do sygnalizowania poleceń, które są przeplatane z normalnym tekstem drukowalnym.

Historia

Konsola systemu Windows udostępnia szeroką powierzchnię interfejsu API dla aplikacji wiersza polecenia klienta w celu manipulowania zarówno buforem wyświetlania danych wyjściowych, jak i buforem wejściowym użytkownika. Jednak inne platformy inne niż Windows nigdy nie zapewniały tego konkretnego podejścia opartego na interfejsie API do środowisk wiersza polecenia, wybierając zamiast tego użyć sekwencji wirtualnych terminali osadzonych w standardowych strumieniach wejściowych i standardowych danych wyjściowych. (Przez pewien czas firma Microsoft obsługiwała to zachowanie we wczesnych wersjach systemu DOS i Windows za pomocą sterownika o nazwie ANSI.SYS).

Natomiast wirtualne sekwencje terminalowe (w różnych dialektach) napędzają operacje środowiska wiersza polecenia dla wszystkich innych platform. Sekwencje te są zakorzenione w standardzie ECMA i serii rozszerzeń przez wielu dostawców, sięgających korzeniami do terminali Digital Equipment Corporation i Tektronix, aż po bardziej nowoczesne i powszechnie używane terminale programowe, takie jak xterm. Wiele rozszerzeń istnieje w domenie sekwencji terminalu wirtualnego, a niektóre sekwencje są częściej obsługiwane niż inne, ale można bezpiecznie powiedzieć, że świat ustandaryzował to jako język poleceń dla środowisk wiersza polecenia z dobrze znanym podzestawem obsługiwanym przez praktycznie każdy terminal i aplikację kliencką wiersza polecenia.

Obsługa wielu platform

Wirtualne sekwencje terminali są natywnie obsługiwane na różnych platformach, dzięki czemu aplikacje terminalowe i narzędzia wiersza polecenia można łatwo przenosić między wersjami i odmianami systemów operacyjnych, z wyjątkiem systemu Windows.

Natomiast interfejsy API konsoli systemu Windows są obsługiwane tylko w systemie Windows. Obszerna biblioteka translacji lub adapter musi być napisana między systemem Windows a terminalem wirtualnym, lub odwrotnie, podczas próby przeniesienia narzędzi wiersza polecenia z jednej platformy na drugą.

Dostęp zdalny

Sekwencje terminali wirtualnych mają główną zaletę dostępu zdalnego. Nie wymagają one dodatkowej pracy do transportu ani wykonywania zdalnych wywołań procedur ponad to, co jest potrzebne do skonfigurowania standardowego połączenia zdalnego wiersza polecenia. Po prostu podłączenie kanału transportowego wychodzącego i przychodzącego (lub jednego kanału dwukierunkowego) przez potok, gniazdo, plik, port szeregowy lub dowolne inne urządzenie wystarcza do przesyłania wszystkich informacji wymaganych przez aplikację komunikującą się tymi sekwencjami do zdalnego hosta.

Wręcz przeciwnie, interfejsy API konsoli systemu Windows były dostępne tylko na komputerze lokalnym, a wszelkie próby ich zdalnego wykorzystania wymagałyby utworzenia całej warstwy interfejsu zdalnego wywoływania i transportu, które wykraczałyby poza zwykły kanał.

Separacja obaw

Niektóre interfejsy API konsoli systemu Windows zapewniają niski poziom dostępu do buforów wejściowych i wyjściowych lub oferują wygodne funkcje do interaktywnych wierszy poleceń. Może to obejmować aliasy i historię poleceń zaprogramowane w podsystemie konsoli i środowisku serwera, zamiast w samej klienckiej aplikacji wiersza poleceń.

Natomiast inne platformy sprawiają, że zapamiętanie bieżącego stanu aplikacji oraz obsługa funkcji wygody jest zadaniem narzędzia wiersza polecenia lub samej powłoki.

Metoda obsługi tej odpowiedzialności przez Konsolę Windows na hoście konsoli i interfejsie API sprawia, że pisanie aplikacji wiersza poleceń z tymi funkcjami jest szybsze i łatwiejsze, przenosi odpowiedzialność zapamiętywania stanu rysunku oraz obsługi funkcji wygody edycji. Jednak to sprawia, że niemal niemożliwe jest zdalne łączenie tych działań między platformami, wersjami lub scenariuszami ze względu na różnice w implementacjach i dostępności. Ten sposób zarządzania odpowiedzialnością sprawia również, że ostateczne interaktywne doświadczenie użytkownika tych aplikacji wiersza polecenia systemu Windows jest całkowicie zależne od implementacji, priorytetów i cyklu wydawania hosta konsolowego.

Na przykład zaawansowane funkcje edytowania wierszy, takie jak wyróżnianie składni i kompleksowy wybór, są możliwe tylko wtedy, gdy aplikacja wiersza poleceń sama obsługuje zagadnienia edytowania. Konsola nigdy nie mogła mieć wystarczającego kontekstu, aby w pełni zrozumieć te scenariusze w szerokim zakresie, jak może to zrobić aplikacja kliencka.

Z kolei inne platformy używają sekwencji terminali wirtualnych do obsługi tych działań i komunikacji terminalu wirtualnego za pośrednictwem bibliotek po stronie klienta wielokrotnego użytku, takich jak readline i ncurses. Końcowy terminal jest odpowiedzialny tylko za wyświetlanie informacji i odbieranie danych wejściowych za pośrednictwem tego dwukierunkowego kanału komunikacyjnego.

Wrong-Way czasowniki

Za pomocą konsoli systemu Windows niektóre akcje można wykonać w kierunku odwrotnym do naturalnego na strumieniach wejściowych i wyjściowych. Dzięki temu aplikacje wiersza polecenia systemu Windows mogą uniknąć problemów związanych z zarządzaniem własnymi buforami. Umożliwia również aplikacjom wiersza polecenia systemu Windows wykonywanie zaawansowanych operacji, takich jak symulowanie/wstrzykiwanie danych wejściowych w imieniu użytkownika, lub odczytywanie niektórych historii tego, co zostało napisane.

Chociaż zapewnia to dodatkowe możliwości aplikacji systemu Windows działających w określonym kontekście użytkownika na jednej maszynie, zwiększa również ryzyko naruszenia zabezpieczeń oraz przełamywania poziomów uprawnień lub domen przy użyciu w niektórych scenariuszach. Takie scenariusze obejmują działanie między kontekstami na tej samej maszynie lub pomiędzy kontekstami na innej maszynie lub w innym środowisku.

Inne platformy, które używają sekwencji terminali wirtualnych, nie zezwalają na to działanie. Celem naszego zalecenia przejścia z klasycznej konsoli systemu Windows na sekwencje terminali wirtualnych jest zbieżność z tą strategią, zarówno ze względów interoperacyjności, jak i bezpieczeństwa.

Bezpośredni dostęp do okien

Powierzchnia interfejsu API konsoli systemu Windows zapewnia dokładny uchwyt do okna hostującego. Dzięki temu narzędzie wiersza polecenia może wykonywać zaawansowane operacje na oknach, korzystając z szerokiej gamy interfejsów API Win32 dozwolonych dla uchwytu okna. Te interfejsy API Win32 mogą manipulować stanem okna, ramką, ikoną lub innymi właściwościami okna.

Natomiast na innych platformach z sekwencjami terminali wirtualnych istnieje wąski zestaw poleceń, które można wykonać w oknie. Te polecenia mogą wykonywać takie czynności, jak zmiana rozmiaru okna lub wyświetlanego tytułu, ale muszą być wykonywane w tym samym pasmie i pod tą samą kontrolą co pozostała część strumienia.

Wraz z rozwojem systemu Windows zwiększono mechanizmy kontroli zabezpieczeń i ograniczenia dotyczące uchwytów okien. Dodatkowo charakter i istnienie uchwytu okna adresowalnego przez aplikację na każdym konkretnym elemencie interfejsu użytkownika uległy ewolucji, zwłaszcza w kontekście zwiększonego wsparcia dla form czynników i platform urządzeń. To powoduje, że bezpośredni dostęp do aplikacji wiersza poleceń staje się podatny na problemy w miarę rozwoju platform i środowisk użytkowych.

Unicode

UTF-8 to akceptowane kodowanie danych Unicode na prawie wszystkich nowoczesnych platformach, ponieważ zapewnia właściwą równowagę między przenośnością, rozmiarem magazynu i czasem przetwarzania. Jednak system Windows historycznie wybrał kodowanie UTF-16 jako podstawowe kodowanie danych Unicode. Obsługa formatu UTF-8 zwiększa się w systemie Windows i korzystanie z tych formatów Unicode nie wyklucza użycia innych kodowań.

Platforma konsoli systemu Windows obsługuje wszystkie istniejące strony kodu i kodowania. W razie potrzeby użyj protokołu UTF-16, aby uzyskać maksymalną zgodność w wersjach systemu Windows i wykonać translacja algorytmiczna za pomocą protokołu UTF-8. Zwiększona obsługa protokołu UTF-8 jest w toku dla systemu konsoli.

Obsługa utF-16 w konsoli może być używana bez dodatkowej konfiguracji za pośrednictwem wariantu W wszystkich interfejsów API konsoli i jest bardziej prawdopodobnym wyborem dla aplikacji już dobrze zorientowanych w utF-16 poprzez komunikację z wariantem wchar_t i W innych funkcji i produktów platformy Microsoft i Windows.

Obsługa UTF-8 w konsoli może być używana za pomocą wariantu interfejsów API konsoli dla uchwytów konsoli po ustawieniu strony kodowej na 65001 lub CP_UTF8 przy użyciu metod SetConsoleOutputCP i SetConsoleCP, w zależności od potrzeby. Ustawienie stron kodu z wyprzedzeniem jest konieczne tylko wtedy, gdy maszyna nie wybrała opcji "Użyj standardu Unicode UTF-8 do obsługi języka na całym świecie" w ustawieniach aplikacji innych niż Unicode w sekcji Region Panelu sterowania.

Uwaga / Notatka

Od tej pory kod UTF-8 jest w pełni obsługiwany na standardowym strumieniu wyjściowym przy użyciu metod WriteConsole i WriteFile . Obsługa strumienia wejściowego różni się w zależności od trybu wejściowego i będzie nadal ulepszana wraz z upływem czasu. Szczególnie domyślne tryby "cooked" na wejściu nie obsługują jeszcze w pełni UTF-8. Bieżący stan tej pracy można znaleźć w witrynie microsoft/terminal#7777 w witrynie GitHub. Obejście polega na użyciu algorytmicznie tłumaczalnego UTF-16 do odczytywania danych wejściowych za pośrednictwem funkcji ReadConsoleW lub ReadConsoleInputW, dopóki nie zostaną rozwiązane zaległe problemy.

Rekomendacje

W przypadku wszystkich nowych i ciągłych programowania w systemie Windows zalecane są sekwencje terminalu wirtualnego jako sposób interakcji z terminalem. Spowoduje to zbieżność aplikacji klienckich wiersza polecenia systemu Windows ze stylem programowania aplikacji na wszystkich innych platformach.

Wyjątki dotyczące używania interfejsów API konsoli systemu Windows

Ograniczony podzbiór interfejsów API konsoli systemu Windows jest nadal niezbędny do ustanowienia środowiska początkowego. Platforma systemu Windows nadal różni się od innych w obsłudze procesów, sygnałów, urządzeń i kodowania:

Planowanie przyszłości i pseudokonsole

Nie ma planów usunięcia interfejsów API konsoli systemu Windows z platformy.

Wręcz przeciwnie, host konsoli systemu Windows oferuje technologię pseudokonsole, aby przetłumaczyć istniejące wywołania aplikacji wiersza polecenia systemu Windows na sekwencje terminali wirtualnych i przekazać je zdalnie lub na różnych platformach do innego środowiska hostingowego.

To tłumaczenie nie jest idealne. Wymaga to, aby okno hosta konsoli utrzymywało środowisko symulowane tego, co Windows wyświetlałby użytkownikowi. Następnie projektuje replikę tego symulowanego środowiska do hosta pseudokonsole . Wszystkie wywołania interfejsu API konsoli systemu Windows są realizowane w środowisku symulowanym, aby sprostać wymaganiom starszej aplikacji klienckiej uruchamianej w wierszu polecenia. Tylko efekty są propagowane do ostatecznego hosta.

Aby aplikacja wiersza polecenia zapewniała pełną zgodność na różnych platformach oraz pełną obsługę wszystkich nowych funkcji i scenariuszy zarówno w systemie Windows, jak i poza nim, zaleca się przejście na sekwencje terminali wirtualnych oraz dostosowanie architektury aplikacji wiersza polecenia do wymogów wszystkich platform.

Więcej informacji o tym przejściu systemu Windows dla aplikacji wiersza polecenia można znaleźć w naszym harmonogramie działania ekosystemu.