GetStdHandle 函数

检索指定标准设备的句柄(标准输入、标准输出或标准错误)。

语法

HANDLE WINAPI GetStdHandle(
  _In_ DWORD nStdHandle
);

参数

nStdHandle [in]
标准设备。 此参数的取值可为下列值之一。

含义
STD_INPUT_HANDLE((DWORD)-10) 标准输入设备。 最初,这是输入缓冲区 CONIN$ 的控制台。
STD_OUTPUT_HANDLE((DWORD)-11) 标准输出设备。 最初,这是活动控制台屏幕缓冲区 CONOUT$
STD_ERROR_HANDLE((DWORD)-12) 标准错误设备。 最初,这是活动控制台屏幕缓冲区 CONOUT$

注意

这些常量的值都是无符号数,但是在头文件中被定义为从有符号数的强制转换,并利用 C 编译器将它们滚动到刚好低于最大 32 位值。 在以不分析标头并重新定义常量的语言与这些句柄交互时,请注意此约束。 例如,((DWORD)-10) 实际上是无符号数 4294967286

返回值

如果该函数成功,则返回值为指定设备的句柄,或为由先前对 SetStdHandle 的调用设置的重定向句柄。 除非应用程序已使用 SetStdHandle 来设置具有较少访问权限的标准句柄,否则该句柄具有 GENERIC_READ 和 GENERIC_WRITE 访问权限

提示

完成后,无需使用 CloseHandle 释放此句柄。 有关详细信息,请参阅注解

如果函数失败,则返回值为 INVALID_HANDLE_VALUE。 要获得更多的错误信息,请调用 GetLastError

如果应用程序没有关联的标准句柄(例如在交互式桌面上运行的服务),并且尚未重定向这些句柄,则返回值为 NULL

备注

GetStdHandle 返回的句柄可供需要在控制台中进行读取或写入的应用程序使用。 创建控制台时,标准输入句柄是控制台输入缓冲区的句柄,而标准输出和标准错误句柄则是控制台的活动屏幕缓冲区的句柄。 这些句柄可供 ReadFileWriteFile 函数使用,也可供访问控制台输入缓冲区或屏幕缓冲区的任何控制台函数(例如 ReadConsoleInputWriteConsoleGetConsoleScreenBufferInfo 函数)使用

可通过调用 SetStdHandle 来重定向进程的标准句柄,在这种情况下,GetStdHandle 会返回重定向的句柄。 如果已重定向标准句柄,则可在对 CreateFile 函数的调用中指定 CONIN$ 值,以获取控制台输入缓冲区的句柄。 同样,你也可指定 CONOUT$ 值来获取控制台的活动屏幕缓冲区的句柄。

以 Main 方法为入口点的进程的标准句柄取决于生成应用程序时传递给链接器的 /SUBSYSTEM 标记的配置。 指定 /SUBSYSTEM:CONSOLE 请求操作系统使用控制台会话在启动时填充句柄,前提是父对象尚未通过继承填充标准句柄表。 相反,/SUBSYSTEM:WINDOWS 意味着应用程序不需要控制台,并且可能不会使用标准句柄。 有关句柄继承的详细信息,请参阅 STARTF_USESTDHANDLES 的文档

某些应用程序在其声明的子系统的边界外运行;例如,/SUBSYSTEM:WINDOWS 应用程序可能会检查/使用用于日志记录或调试的标准句柄,但使用图形用户界面正常运行。 这些应用程序需要仔细探查标准句柄的状态,并在需要时使用 AttachConsoleAllocConsoleFreeConsole 添加/删除控制台

某些应用程序可能还会改变其对继承句柄类型的行为。 可使用 GetFileType 消除控制台、管道和文件等之间各类型的歧义

句柄释放

处理完从 GetStdHandle 检索到的句柄时,不需要执行 CloseHandle。 返回的值只是进程表中存储的值的副本。 进程本身通常被视为这些句柄及其生存期的所有者。 每个句柄在创建时都放置在表中,具体取决于 CreateProcess 调用的继承和启动具体信息,并且将在进程销毁时释放

对于有意尝试替换这些句柄或阻止进程的其他部分使用它们的应用程序来说,手动操作这些句柄的生存期可能是可取的。 由于可通过运行代码缓存 HANDLE,因此该代码不一定会拾取通过 SetStdHandle 所做的更改。 通过 CloseHandle 显式关闭句柄将在进程范围内关闭该句柄,并且任何缓存引用的下一次使用都将遇到错误

在进程表中替换标准句柄的指导原则是使用 GetStdHandle 从表中获取现有的 HANDLE,使用 SetStdHandle 将新的 HANDLE 放入使用 CreateFile(或类似函数)打开的文件中,然后关闭检索到的句柄

GetStdHandle 或 SetStdHandle 函数都不验证作为句柄存储在进程表中的值。 在实际读/写操作(如 ReadFile 或 WriteFile)时执行验证

附加/分离行为

附加到新控制台时,除非在进程创建期间指定了 STARTF_USESTDHANDLES,否则标准句柄始终会替换为控制台句柄

如果标准句柄的现有值为 NULL,或者标准句柄的现有值与控制台句柄 pseudohandle 类似,则该句柄会被替换为控制台句柄

当父对象使用 CREATE_NEW_CONSOLE 和 STARTF_USESTDHANDLES 创建控制台进程时,除非标准句柄的现有值为 NULL 或为 控制台句柄 pseudohandle,否则不会替换标准句柄

注意

控制台进程启动时必须已填充标准句柄,否则它们将使用新控制台的适当句柄自动进行填充。 图形用户界面 (GUI) 应用程序可在没有标准句柄的情况下启动,它们不会自动进行填充。

示例

有关示例,请参阅读取输入缓冲区事件

要求

   
最低受支持的客户端 Windows 2000 Professional [仅限桌面应用]
最低受支持的服务器 Windows 2000 Server [仅限桌面应用]
Header ProcessEnv.h (via Winbase.h, include Windows.h)
Kernel32.lib
DLL Kernel32.dll

另请参阅

控制台函数

控制台句柄

CreateFile

GetConsoleScreenBufferInfo

ReadConsoleInput

ReadFile

SetStdHandle

WriteConsole

WriteFile