附着到一个控制台
一个进程可以使用
AttachConsole
函数来附着到一个控制台上,一个进程只能附着一个控制台。
一个控制台可以有许多进程附着到它上面,调用
GetConsoleProcessList
函数可以得到附着到一个控制台的列表。
关闭一个控制台
进程可以使用
FreeConsole
函数来将其自身从一个控制台脱离出来。如果其他进程共享这个控制台,控制台不会被销毁,但调用
FreeConsole
函数的进程不能在使用它了,在进程调用
FreeConsole
之后,它可以使用
AllocConsole
来创建一个新的控制台或
AttachConsole
来附着到另一个控制台上。
控制在最后一个附着的进程关闭的时候或调用
FreeConsole
的时候被关闭。
控制台句柄
控制台进程使用句柄来访问控制台的输入和屏幕缓冲区。一个进程可以使用
GetStdHandle
、
CreateFile
或
CreateConsoleScreenBuffer
函数来打开这些句柄。
GetStdHandle
函数提供一个获得进程相关的标准输入(
STDIN
)、标准输出(
STDOUT
)和标准错误(
STDERR
)句柄。在控制台创建过程中,系统创建这些句柄。最初的
STDIN
是一个指向控制台输入缓冲区的句柄,
STDOUT
和
STDERR
是控制台活动屏幕缓冲区的句柄。然而,
SetStdHandle
函数可以改变
STDIN
、
STDOUT
、
STDERR
关联的句柄来重定向标准句柄。因为父进程的标准句柄可以被子进程继承,后面调用
GetStdHandle
函数返回的是重定向的句柄。
GetStdHandle
返回的句柄可以指向其他的句柄不一定是控制台
I/O
。例如,在创建子进程之前,父亲进程使用
SetStdHandle
来将
STDIN
设置为一个管道句柄,那么这个特性会被子进程继承。当子进程调用
GetStdHandle
的时候返回的是管道句柄。这意味着父亲进程能控制子进程的标准句柄,
GetStdHandle
返回的句柄有
GENERIC_READ|GENERIC_WRITE
访问权限,当然如果在
SetStdHandle
的时候设置较少的访问权限另外说。
GetStdHandle
返回的句柄值不是
0
,
1
,
2
,因此在
Stdio.h
(
STDIN
,
STDOUT
和
STDERR
)中预定义的流常量不能在需要一个控制台句柄的函数中使用。
CreateFile
函数即使
STDIN
和
STDOUT
没有被重定向的情况下,也可以让一个进程得到输入缓冲区和活动屏幕缓冲区的句柄。为了打开一个控制台输入缓冲区的句柄,需要在调用
CreateFile
的时候指定
CONIN$
值,而指定
CONOUT$
值可以打开一个控制台活动屏幕缓冲区的句柄。
CreateFile
函数使你可以通过它返回的句柄来读写操作。
函数
CreateConsoleScreenBuffer
创建一个新的屏幕缓冲区且返回这个句柄,这个句柄可以在所有接受一个控制输出作为参数的函数中使用。新的屏幕缓冲区不会是活动的,只有调用
SetConsoleActiveScreenBuffer
函数的时候指定该值才会被设置为活动的。活动屏幕缓冲区的改变不会改变
GetStdHandle
的值,同样使用
SetStdHandle
改变
STDOUT
句柄也不会影响活动屏幕缓冲区。
CreateFile
和
CreateConsoleScreenBuffer
函数返回的句柄能在任何需要控制台输入缓冲区或控制台屏幕缓冲区作为参数的函数中,
GetStdHandle
返回的句柄只要没有被重定向为其他的句柄都可以在控制台函数中使用,如果标准句柄被重定向为指向一个文件或管道,这些句柄只能被
ReadFile
和
WriteFile
函数使用。
进程可以使用
DuplicateHandle
函数来创建一个控制台句柄的副本,可以指定不同的访问和继承权限。注意,进程可以自己使用而创建一个控制台句柄副本。这与其他的句柄类型不同(例如文件、管道、信号量对象),这些类型可以通过
DuplicateHandle
来创建一个有效的句柄,而别的进程也可以使用。