附著到一個控制台
一個進程可以使用 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 來建立一個有效控制代碼,而別的進程也可以使用。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=697517