认识控制台-控制台句柄、附着到控制台、关闭控制台
1. 附著到一個控制臺
? ? ? ? 一個進程可以使用 AttachConsole 函數來附著到一個控制臺上,一個進程只能附著一個控制臺。
? ? ? ?一個控制臺可以有許多進程附著到它上面,調用 GetConsoleProcessList 函數可以得到附著到一個控制臺的列表。
?
2. 關閉一個控制臺
? ? ? 進程可以使用 FreeConsole 函數來將其自身從一個控制臺脫離出來。如果其他進程共享這個控制臺,控制臺不會被銷 毀,但調用 FreeConsole 函數的進程不能在使用它了,在進程調用 FreeConsole 之后,它可以使用 AllocConsole 來創建一個新的控制臺或 AttachConsole 來附著到另一個控制臺上。控制在最后一個附著的進程關閉的時候或調用 FreeConsole 的時候被關閉。
?
3. 控制臺句柄
? ? ? 控制臺進程使用句柄來訪問控制臺的輸入和屏幕緩沖區。一個進程可以使用 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 來創建一個有效的句柄,而別的進程也可以使用。總結
以上是生活随笔為你收集整理的认识控制台-控制台句柄、附着到控制台、关闭控制台的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用CreateProcess和wcsc
- 下一篇: #pragma pack(n)和size