Как заставить консоль win32 распознавать escape-последовательности ANSI/VT100?
Я создаю облегченную версию библиотеки ncurses. Пока что он работает довольно хорошо с VT100-совместимыми терминалами, но консоль win32 не может распознать \033
код как начало escape-последовательности:
# include <stdio.h>
# include "term.h"
int main(void) {
puts(BOLD COLOR(FG, RED) "Bold text" NOT_BOLD " is cool!" CLEAR);
return 0;
}
Что необходимо сделать на уровне кода C, чтобы драйвер ANSI.SYS был загружен и распознавались escape-последовательности ANSI/VT100?
14 ответов
[ОБНОВЛЕНИЕ] Для последней версии Windows 10, пожалуйста, прочитайте полезный вклад @brainslugs83, чуть ниже в комментариях к этому ответу.
Хотя для версий до Windows 10 Anniversary Update
:
ANSI.SYS имеет ограничение, что он может работать только в контексте подсистемы MS-DOS под Windows 95-Vista.
Microsoft KB101875 объясняет, как включить ANSI.SYS в командном окне, но это не относится к Windows NT. Согласно статье: все мы любим цвета, современные версии Windows не имеют такой хорошей поддержки ANSI.
Вместо этого Microsoft создала множество функций, но это далеко от необходимости использовать управляющую последовательность ANSI/VT100.
Для более подробного объяснения смотрите статью в Википедии:
ANSI.SYS также работает в системах, производных от NT, для 16-битных устаревших программ, выполняемых под NTVDM.
Консоль Win32 вообще не поддерживает escape-последовательности ANSI. Программное обеспечение, такое как Ansicon, может, однако, выступать в качестве оболочки вокруг стандартной консоли Win32 и добавлять поддержку escape-последовательностей ANSI.
Поэтому я думаю, что ANSICON от Jason Hood - это ваше решение. Он написан на C, поддерживает 32-битные и 64-битные версии Windows, и источник доступен.
Также я нашел другой похожий вопрос или пост, на который в конечном итоге был дан ответ на использование ANSICON:
Начиная с Windows 10 TH2 (v1511), conhost.exe
а также cmd.exe
Поддержка последовательностей выхода ANSI и VT100 из коробки (хотя они должны быть включены).
Смотрите мой ответ в superuser для более подробной информации.
На основе @BrainSlugs83 вы можете активировать текущую версию Windows 10 через регистр с помощью этой командной строки:
REG ADD HKCU\CONSOLE /f /v VirtualTerminalLevel /t REG_DWORD /d 1
Для Python 2.7 у меня нормально работает следующий скрипт с Windows 10 (v1607)
import os
print '\033[35m'+'color-test'+'\033[39m'+" test end"
os.system('') #enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607
print '\033[35m'+'color-test'+'\033[39m'+" test end"
Результат должен быть:
[35mcolor-test[39m test end
color-test test end
Начиная с Windows 10, вы можете использовать ENABLE_VIRTUAL_TERMINAL_PROCESSING
чтобы включить escape-последовательности ANSI:
https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
Если ANSICON неприемлем, поскольку он требует установки чего-либо в системе, более легкое решение, которое анализирует и транслирует коды ANSI в соответствующие функции консоли Win32 API, такие как SetConsoleTextAttribute.
Для окраски cmd вам нужно Windows.h
и использовать SetConsoleTextAttribute()
Более подробную информацию можно найти в http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx
В последнем win10 это может быть сделано SetConsoleMode(originMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
, См. https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
Может быть, ANSICON может помочь вам
Просто загрузите и извлеките файлы, в зависимости от вашей ОС Windows: 32-битной или 64-битной
Установите его с помощью: ansicon -i
Ansi.sys (в папке system32) - это "драйвер MSDOS", предоставляемый как часть Windows XP, 2000 и более ранних версий NT. В 2000 и XP он находится в папке system32 (я не помню структуру более ранних версий NT). Программы, работающие в подсистеме DOS и использующие стандартный вывод, могут использовать ANSI.SYS так же, как они работают в MSDOS.
Чтобы загрузить ansi.sys, вы должны использовать команду device= или devicehigh= в конфигурации, как в MSDOS. В Windows NT 5 (2K & XP) каждой копии подсистемы DOS может быть предоставлен отдельный файл конфигурации в pif/ ярлыке (используйте кнопку "Дополнительно"), и существует файл по умолчанию, называемый CONFIG.NT (также в папка system32), которая используется, если pif/ ярлык не указывает специальный файл конфигурации.
Когда ansi.sys загружен правильно, mem /d сообщит, что он загружен. В более ранних версиях NT вы можете и должны загрузить подходящую среду DOS для загрузки ansi.sys, и ANSI Art будет работать при появлении запроса. На Win 2K и XP загрузка ansi.sys не будет влиять на ваше "приглашение CMD", потому что CMD не является программой DOS: это 32-разрядная консольная программа Windows. По какой-то причине, которую я не понимаю, в WinXP, даже если вы загрузите фиксированную копию command.com с помощью "command.com /p", командная строка не будет включена ANSI: возможно, когда вы делаете это таким образом, это только эмулирует загрузку command.com?
В любом случае, когда вы используете актуальную DOS-версию command.com, ansi включается после загрузки: вы можете продемонстрировать его использование с небольшим количеством ANSI-артов, таких как:
command /c type ansiart.ans
(вот пример: http://artscene.textfiles.com/ansi/artwork/beastie.ans)
CONFIG.NT (в папке system32) содержит пример синтаксиса для загрузки драйверов устройств. Вы должны быть администратором, чтобы редактировать этот файл по умолчанию, или вы можете сделать его копию.
В Win 2K и XP "ярлыком" по умолчанию для MSDOS является файл.PIF, а не файл.LNK. Если вы создадите файл.lnk для CMD, вы не сможете установить специальные файлы config и autoexec, он будет использовать файл CONFIG.NT по умолчанию. Если вы хотите использовать специальный файл конфигурации только для одного приложения DOS, вы можете сделать копию "ярлыка MSDOS" или копию "_default.pif", которая находится в папке Windows.
Была такая же проблема. Я установил ConEmu, и это решило мою проблему.
Мне лично нравится клинк. Он не только обрабатывает коды ANSI, но и добавляет множество других функций, поэтому консоль Windows ведет себя как bash (история, обратный поиск в истории, сочетания клавиш и т. Д.):
- Редактирование той же строки, что и в Bash (из библиотеки Readline GNU).
- Постоянство истории между сессиями.
- Контекстно-зависимое завершение;
- Исполняемые файлы (и псевдонимы).
- Каталог команд.
- Переменные среды
- Сторонние инструменты; Git, Mercurial, SVN, Go и P4.
- Новые сочетания клавиш;
- Вставить из буфера обмена (Ctrl-V).
- Инкрементальный поиск по истории (Ctrl-R / Ctrl-S).
- Мощное завершение (TAB).
- Отменить (Ctrl-Z).
- Автоматическая "cd.." (Ctrl-PgUp).
- Расширение переменной среды (Ctrl-Alt-E).
- (нажмите Alt-H, чтобы узнать больше...)
- Завершение сценария с Lua.
- Цветная и скриптовая подсказка.
- Автоответчик на запрос "Завершить пакетное задание?".
Я обнаружил, что этот инструмент работает для моей цели. Microsoft Color Tool от GitHub
Разархивируйте сжатый файл, затем откройте CMD с разрешения администратора.
Перейдите в папку, в которую вы распаковываете файл в CMD.
Затем выполните эту командуcolortool -b scheme-name
"
Имя схемы необходимо заменить любой из следующих опций:
- campbell.ini
- Кемпбелл-legacy.ini
- CMD-legacy.ini
- deuternopia.itermcolors
- OneHalfDark.itermcolors
- OneHalfLight.itermcolors
- solarized_dark.itermcolors
- solarized_light.itermcolors
В моем случае команда будет такойcolortool -b solarized_dark.itermcolors
"
Нажмите справа в окне консоли и выберите Свойства.
Вам не нужно менять какое-либо значение, просто нажмите "ОК", чтобы сохранить настройки. (Вы заметите, что ваш шрифт уже содержит цвета).
Затем перезапустите ваш cmd или powerShell.
Цвет ANSI должен быть включен и работать с выбранной ранее цветовой схемой.
Каким-то образом в Windows вам просто нужно сначала вызвать любую команду оболочки, а неsystem
функция. Просто в начале вашего основного метода поставьтеsystem("");
, и не забудьте включитьstdlib.h
.
Я заметил это, когда просматривал некоторые из своих старых программ, которые также использовали коды ANSI, чтобы понять, почему они работают, но мой новый код не работает.