Прочитать на английском

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


Функция GetStdHandle

Извлекает дескриптор для указанного стандартного устройства (стандартный ввод, стандартный вывод или стандартная ошибка).

Синтаксис

HANDLE WINAPI GetStdHandle(
  _In_ DWORD nStdHandle
);

Параметры

nStdHandle [ввод]
Стандартное устройство. Этот параметр может принимать одно из указанных ниже значений.

Значение Значение
STD_INPUT_HANDLE ((DWORD)-10) Стандартное устройство ввода. Изначально это входной буфер консоли, CONIN$.
STD_OUTPUT_HANDLE ((DWORD)-11) Стандартное выходное устройство. Изначально это активный буфер экрана консоли, CONOUT$.
STD_ERROR_HANDLE ((DWORD)-12) Устройство стандартных ошибок. Изначально это активный буфер экрана консоли, CONOUT$.

Примечание

Значения этих констант являются числами без знака, но определяются в файлах заголовков как приведение из числа со знаком и используют компилятор C для их преобразования к 32-разрядному значению, которое ниже максимального. При взаимодействии с этими дескрипторами на языке, который не анализирует заголовки и переопределяет константы, следует учитывать это ограничение. В качестве примера ((DWORD)-10) — это число 4294967286 без знака.

Возвращаемое значение

Если функция выполняется успешно, возвращается дескриптор для указанного устройства или перенаправленный дескриптор, заданный предыдущим вызовом метода SetStdHandle. Дескриптор имеет права доступа GENERIC_READ и GENERIC_WRITE, если только с помощью метода SetStdHandle в приложении не был задан стандартный дескриптор с более ограниченным доступом.

Совет

По завершении работы удалять этот дескриптор с помощью CloseHandle необязательно. Дополнительные сведения см. в примечаниях.

Если функция завершается неудачно, возвращается значение INVALID_HANDLE_VALUE. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.

Если приложение не имеет связанных стандартных дескрипторов, например службы, работающей на интерактивном рабочем столе, и не перенаправляет их, возвращается значение NULL.

Замечания

Дескрипторы, возвращаемые методом GetStdHandle, могут использоваться приложениями, которые должны выполнять чтение или запись данных в консоли. При создании консоли стандартный дескриптор ввода представляет собой дескриптор для входного буфера консоли, а стандартный дескриптор вывода и стандартный дескриптор ошибок являются дескрипторами активного буфера экрана консоли. Эти дескрипторы могут использоваться функциями ReadFile и WriteFile или любыми консольными функциями, которые обращаются к входному буферу консоли или буферу экрана (например, функции ReadConsoleInput, WriteConsole или GetConsoleScreenBufferInfo).

Стандартные дескрипторы процесса могут перенаправляться с помощью вызова SetStdHandle. В этом случае GetStdHandle возвращает перенаправленный дескриптор. Если стандартные дескрипторы были перенаправлены, можно указать значение CONIN$ в вызове функции CreateFile, чтобы получить дескриптор для входного буфера консоли. Аналогичным образом можно указать значение CONOUT$, чтобы получить дескриптор для активного буфера экрана консоли.

Стандартные дескрипторы процесса вначале метода main определяются конфигурацией флага /SUBSYSTEM, переданного компоновщику при создании приложения. Если указать /SUBSYSTEM:CONSOLE, операционная система получит запрос на заполнение дескрипторов данными сеанса консоли при запуске, если родительский объект еще не заполнил стандартную таблицу дескрипторов путем наследования. /SUBSYSTEM:WINDOWS, в свою очередь, означает, что приложению не нужна консоль и, скорее всего, не будут использоваться стандартные дескрипторы. Дополнительные сведения о наследовании дескриптора можно найти в документации по STARTF_USESTDHANDLES.

Некоторые приложения работают за пределами границ объявленной подсистемы. Например, приложение /SUBSYSTEM:WINDOWS может проверять или использовать стандартные дескрипторы для ведения журнала или отладки, но нормально работать с графическим пользовательским интерфейсом. Эти приложения должны тщательно проверять состояние стандартных дескрипторов при запуске и использовать AttachConsole, AllocConsole и FreeConsole, чтобы добавить или удалить консоль при необходимости.

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

Освобождение дескриптора

По завершении работы с дескриптором, полученным от GetStdHandle, использовать CloseHandle необязательно. Возвращаемое значение — это просто копия значения, хранимого в таблице процессов. Сам процесс, как правило, считается владельцем этих дескрипторов и их времени существования. Каждый дескриптор помещается в таблицу при создании в зависимости от наследования. При этом выполняется определенный вызов CreateProcess, и дескриптор будет освобожден при уничтожении процесса.

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

Действия по замене стандартного дескриптора в таблице процессов заключаются в получении существующего экземпляра HANDLE из таблицы с помощью GetStdHandle. Используйте SetStdHandle для размещения нового экземпляра HANDLE в экземпляр, открытый с помощью CreateFile (или аналогичной функции), а затем закрытия полученного дескриптора.

Проверка значений, хранимых в виде дескрипторов в таблице процессов, функциями GetStdHandle или SetStdHandle не выполняется. Проверка выполняется во время фактической операции чтения или записи, такой как ReadFile или WriteFile.

Поведение при подключении и отключении

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

Если имеющееся значение стандартного дескриптора равно NULL или выглядит как псевдодескриптор консоли, этот дескриптор заменяется дескриптором консоли.

Если родительский элемент для создания консольного процесса использует CREATE_NEW_CONSOLE и STARTF_USESTDHANDLES, стандартные дескрипторы не будут заменены, если только стандартный дескриптор не имеет значение NULL или имеющееся значение не является псевдодескриптором.

Примечание

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

Примеры

Пример см. в статье о чтении событий входного буфера.

Требования

   
Минимальная версия клиента Windows 2000 Professional [только классические приложения]
Минимальная версия сервера Windows 2000 Server [только классические приложения]
Верхний колонтитул ProcessEnv.h (через Winbase.h, включая Windows.h)
Библиотека Kernel32.lib
DLL-библиотеки Kernel32.dll

См. также

Функции консоли

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

CreateFile

GetConsoleScreenBufferInfo

ReadConsoleInput

ReadFile

SetStdHandle

WriteConsole

WriteFile