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


Дескрипторы консоли

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

Функция GetStdHandle предоставляет механизм получения стандартных входных данных (), стандартных выходных данных (STDINSTDOUT) и стандартных дескрипторов ошибок,STDERR связанных с процессом. Во время создания консоли система создает эти дескрипторы. STDIN Изначально это дескриптор входного буфера консоли и STDOUTSTDERR дескриптор активного буфера экрана консоли. Однако функция SetStdHandle может перенаправить стандартные дескрипторы, изменив дескриптор, связанный с STDIN, STDOUTили STDERR. Так как стандартные дескриптора родительского объекта наследуются любым дочерним процессом, последующие вызовы GetStdHandle возвращают перенаправленный дескриптор. Таким образом, дескриптор, возвращаемый GetStdHandle , может ссылаться на то, что отличается от операций ввода-вывода консоли. Например, перед созданием дочернего процесса родительский процесс может использовать SetStdHandle , чтобы задать дескриптор STDIN канала, который наследуется дочерним процессом. Когда дочерний процесс вызывает GetStdHandle, он получает дескриптор канала. Это означает, что родительский процесс может управлять стандартными дескрипторами дочернего процесса. Маркеры, возвращаемые GetStdHandle , имеют GENERIC_READ | GENERIC_WRITE доступ, если не используется SetStdHandle , чтобы задать стандартный дескриптор с меньшим доступом.

Значение дескрипторов, возвращаемых GetStdHandle , не равно 0, 1 и 2, поэтому стандартные предопределенные константы потоков в Stdio.h (STDIN, STDOUTи STDERR) нельзя использовать в функциях, требующих дескриптора консоли.

Функция CreateFile позволяет процессу получить дескриптор входного буфера консоли и активный буфер экрана, даже если STDIN он STDOUT был перенаправлен. Чтобы открыть дескриптор входного буфера консоли, укажите CONIN$ значение в вызове CreateFile. CONOUT$ Укажите значение в вызове CreateFile, чтобы открыть дескриптор активного буфера экрана консоли. CreateFile позволяет указать доступ на чтение и запись возвращаемого дескриптора.

Функция CreateConsoleScreenBuffer создает новый буфер экрана и возвращает дескриптор. Этот дескриптор можно использовать в любой функции, которая принимает дескриптор для вывода консоли. Новый буфер экрана не активен (отображается), пока его дескриптор не указан в вызове функции SetConsoleActiveScreenBuffer . Обратите внимание, что изменение активного буфера экрана не влияет на дескриптор, возвращаемый GetStdHandle. Аналогично использование SetStdHandle для изменения STDOUT дескриптора не влияет на активный буфер экрана.

Дескриптор консоли, возвращаемый CreateFile и CreateConsoleScreenBuffer , можно использовать в любой из консольных функций, требующих дескриптора входного буфера консоли или буфера экрана консоли. Дескриптор, возвращаемый GetStdHandle , может использоваться функциями консоли, если они не были перенаправлены для ссылки на что-то, отличное от операций ввода-вывода консоли. Если стандартный дескриптор был перенаправлен для ссылки на файл или канал, однако дескриптор может использоваться только функциями ReadFile и WriteFile . GetFileType помогает определить тип устройства, на который ссылается дескриптор. Дескриптор консоли представляет собой FILE_TYPE_CHAR.

Процесс может использовать функцию DuplicateHandle для создания повторяющегося дескриптора консоли с другим доступом или наследованием от исходного дескриптора. Обратите внимание, что процесс может создать повторяющийся дескриптор консоли только для собственного использования. Это отличается от других типов дескрипторов (например, файлов, каналов или объектов мьютекса), для которых Дубликат Может создать дубликат , допустимый для другого процесса. Доступ к консоли должен быть предоставлен во время создания другого процесса или может запрашиваться другим процессом через механизм AttachConsole .

Чтобы закрыть дескриптор консоли, процесс может использовать функцию CloseHandle .