控制台句柄
控制台进程使用句柄访问其控制台的输入缓冲区和屏幕缓冲区。 进程可以使用 GetStdHandle、CreateFile 或 CreateConsoleScreenBuffer 函数来打开其中一个句柄。
GetStdHandle 函数提供了一种机制,用于检索与进程关联的标准输入 (STDIN
)、标准输出 (STDOUT
) 和标准错误 (STDERR
) 句柄。 在控制台创建过程中,系统将创建这些句柄。 最初,STDIN
是控制台输入缓冲区的句柄,而 STDOUT
和 STDERR
是控制台活动屏幕缓冲区的句柄。 但是,SetStdHandle 函数可以通过更改与 STDIN
、STDOUT
或 STDERR
关联的句柄来重定向标准句柄。 由于父进程的标准句柄由任何子进程继承,因此后续对 GetStdHandle 的调用会返回重定向的句柄。 因此,GetStdHandle 返回的句柄可能引用的不是控制台 I/O。 例如,在创建子进程之前,父进程可以使用 SetStdHandle 将管道句柄设置为子进程继承的 STDIN
句柄。 当子进程调用 GetStdHandle 时,它会获取管道句柄。 这意味着父进程可以控制子进程的标准句柄。 除非已使用 SetStdHandle 将标准句柄设置为具有较低的访问权限,否则 GetStdHandle 返回的句柄具有 GENERIC_READ | GENERIC_WRITE
访问权限。
GetStdHandle 返回的句柄的值不是 0、1 和 2,因此在需要控制台句柄的函数中,不能使用 Stdio.h(STDIN
、STDOUT
和 STDERR
)中的标准预定义流常量。
通过 CreateFile 函数,即使 STDIN
和 STDOUT
已重定向,进程也可以获取其控制台的输入缓冲区和活动屏幕缓冲区的句柄。 若要打开控制台输入缓冲区的句柄,请在对 CreateFile 的调用中指定 CONIN$
值。 在对 CreateFile 的调用中指定 CONOUT$
值,以打开控制台活动屏幕缓冲区的句柄。 通过 CreateFile 可以指定它所返回的句柄的读取/写入访问权限。
CreateConsoleScreenBuffer 函数会创建新的屏幕缓冲区并返回一个句柄。 此句柄可用于任何接受控制台输出句柄的函数。 新屏幕缓冲区处于非活动(显示)状态,直到在对 SetConsoleActiveScreenBuffer 函数的调用中指定了其句柄。 请注意,更改活动屏幕缓冲区不会影响 GetStdHandle 返回的句柄。 同样,使用 SetStdHandle 更改 STDOUT
句柄不会影响活动屏幕缓冲区。
CreateFile 和 CreateConsoleScreenBuffer 返回的控制台句柄可用于需要控制台输入缓冲区句柄或控制台屏幕缓冲区句柄的任何控制台函数。 如果尚未将 GetStdHandle 返回的句柄重定向为引用控制台 I/O 之外的其他内容,则这些句柄可由控制台函数使用。 但是,如果标准句柄已重定向为引用文件或管道,则该句柄仅可由 ReadFile 和 WriteFile 函数使用。 GetFileType 可帮助确定句柄引用的设备类型。 控制台句柄表示为 FILE_TYPE_CHAR
。
进程可以使用 DuplicateHandle 函数来创建与原始句柄具有不同的访问权限或可继承性的副本控制台句柄。 但请注意,进程创建的副本控制台句柄只能供自己使用。 这不同于其他句柄类型(如文件、管道或互斥对象),对于其他类型,DuplicateHandle 可以创建对其他进程有效的副本。 在其他进程的创建过程中,必须共享对控制台的访问权限,或者其他进程可以通过 AttachConsole 机制请求对控制台的访问权限。
若要关闭控制台句柄,进程可以使用 CloseHandle 函数。