创建控制台
系统启动控制台进程时会创建一个新的控制台,该进程是字符模式进程,其入口点为主函数。 例如,当系统启动命令处理程序 cmd.exe
时,将创建一个新的控制台。 命令处理程序启动新的控制台进程时,用户可以指定系统是为新进程创建新的控制台,还是继承该命令处理程序的控制台。
进程可以使用以下方法之一创建控制台:
- 图形用户界面 (GUI) 或控制台进程可以将 CreateProcess 函数与 CREATE_NEW_CONSOLE 一起使用,以创建控制台进程以及新的控制台。 (默认情况下,控制台进程会继承其父进程的控制台,并且无法保证输入由其预期的进程所接收。)
- 当前未附加到控制台的 GUI 或控制台进程可以使用 AllocConsole 函数来创建新的控制台。 (GUI 进程在创建时不会附加到控制台。如果控制台进程是使用 CreateProcess 和 DETACHED_PROCESS 创建的,则这些进程不会附加到控制台。)
通常,当发生需要与用户交互的错误时,进程使用 AllocConsole 来创建控制台。 例如,GUI 进程可以在发生错误而无法使用其常规图形界面时创建控制台,或者通常不与用户交互的控制台进程可以创建控制台以显示错误。
进程还可以通过在对 CreateProcess 的调用中指定 CREATE_NEW_CONSOLE 标志来创建控制台。 此方法会创建一个新的控制台,子进程可以访问该控制台,但父进程无法访问。 通过使用单独的控制台,使父进程和子进程均可与用户进行交互,而不会发生冲突。 如果在创建控制台进程时未指定此标志,则这两个进程都将附加到同一控制台上,并且无法保证输入由其预期的正确进程所接收。 应用程序可以通过以下方法避免混乱:创建不继承输入缓冲区句柄的子进程,或者一次仅让一个子进程可以继承输入缓冲区句柄,同时在子进程完成前阻止父进程读取控制台输入。
创建新的控制台会生成一个新的控制台窗口,以及用于屏幕输出和用户输入的独立 I/O 缓冲区。 与新控制台关联的进程使用 GetStdHandle 函数获取新控制台的输入和屏幕缓冲区的句柄。 这些句柄使进程能够访问控制台。
当进程使用 CreateProcess 时,它可以指定 STARTUPINFO 结构,该结构的各部分控制为子进程创建的第一个新控制台(如果有)的特性。 如果已指定 CREATE_NEW_CONSOLE 标志,则在对 CreateProcess 的调用中指定的 STARTUPINFO 结构会影响创建的控制台。 如果子进程随后使用 AllocConsole,则它也会影响创建的控制台。 可以指定以下控制台特性:
- 新控制台窗口的大小(以字符单元格表示)
- 新控制台窗口的位置(以屏幕像素坐标表示)
- 新控制台屏幕缓冲区的大小(以字符单元格表示)
- 新控制台屏幕缓冲区的文本和背景色属性
- 新控制台窗口标题栏的显示名称
如果未指定 STARTUPINFO 值,系统将使用默认值。 子进程可以使用 GetStartupInfo 函数来确定其 STARTUPINFO 结构中的值。
进程无法更改其控制台窗口在屏幕上的位置,但以下控制台函数可用于设置或检索在 STARTUPINFO 结构中指定的其他属性。
函数 | 说明 |
---|---|
GetConsoleScreenBufferInfo | 检索窗口大小、屏幕缓冲区大小和颜色属性。 |
SetConsoleWindowInfo | 更改控制台窗口的大小。 |
SetConsoleScreenBufferSize | 更改控制台屏幕缓冲区的大小。 |
SetConsoleTextAttribute | 设置颜色属性。 |
SetConsoleTitle | 设置控制台窗口标题。 |
GetConsoleTitle | 检索控制台窗口标题。 |
进程可以使用 FreeConsole 函数将自己从继承的控制台或由 AllocConsole 创建的控制台中分离。
进程在使用 FreeConsole 从其自己的会话中分离后(或者如果没有附加的会话),可以使用 AttachConsole 函数将其自身附加到另一个现有的控制台会话。