2010-05-12 112 views
0

是否有可能以某種方式更改Windows上的標準I/O功能句柄?提供的語言是C++。如果我理解正確,通過選擇控制檯項目,編譯器只需爲您預先分配控制檯,並操作所有標準I/O函數以處理其句柄。所以,我想要做的是讓一個控制檯應用程序實際寫入另一個應用程序控制臺緩衝區。雖然我可以獲得第一個控制檯句柄,但是通過文件將其傳遞給第二個應用程序(我不太瞭解進程間通信,而且這看起來很簡單),並且以某種方式用於第一個應用程序句柄的prinf。這可以做到嗎?我知道如何獲得控制檯句柄,但我不知道如何將printf重定向到該句柄。它只是爲了學習目的而更加了解OS背後的工作。我感興趣的是printf如何知道它所控制的控制檯。更改默認控制檯I/O功能句柄

回答

0

如果我理解你正確,你可以在http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx找到你想寫的應用程序的源代碼。這個例子展示瞭如何寫stdin的另一個應用程序,並閱讀它的stdout

一般理解。編譯器不會「爲您預先分配控制檯」。編譯器使用在輸出中寫入的標準C/C++庫。所以,如果你使用例如printf()下面的代碼將在年底執行的樣子:

void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters 
{ 
    DWORD n; 
    UINT uCodePage = GetOEMCP(); // CP_OEMCP, CP_THREAD_ACP, CP_ACP 
    PSTR pszText = _alloca (uTextLenght); 

    // in the console are typically not used UNICODE, so 
    if (WideCharToMultiByte (uCodePage, 0, pszwText, uTextLenght, 
          pszText, uTextLenght, NULL, NULL) != (int)uTextLenght) 
     return; 

    WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL); 
    //_tprintf (TEXT("%.*ls"), uTextLenght, pszText); 
    //_puttchar(); 
    //fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout); 
    //_write (
} 

所以,如果一個人改變的STD_OUTPUT_HANDLE的值的所有輸出將去一個文件/管材等。如果程序使用WriteConsole而不是WriteFile這樣的重定向功能不起作用,但標準C/C++庫不這樣做。

如果您不想從子進程中重定向stdout,而是從當前進程中直接調用SetStdHandle()(請參閱http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx)。

「控制檯分配」做一個操作系統的加載程序。它看起來是二進制EXE文件(IMAGE_OPTIONAL_HEADER的子系統部分,參見http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx),如果EXE在這個地方有3個(IMAGE_SUBSYSTEM_WINDOWS_CUI),它會使用父進程的控制檯或創建一個新進程。可以在CreateProcess調用的參數中改變一點這種行爲(但只有當您在代碼中啓動子進程時)。您在鏈接器開關/子系統方面定義的EXE標誌(請參閱http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx)。

0

如果你想printf重定向到一個手柄(FILE *),只是做

fprintf(handle, "..."); 

例如複製printffprintf

fprintf(stdout, "..."); 

或錯誤報告

fprintf(stderr, "FATAL: %s fails", "smurf"); 

這也是你寫入文件的方式。 fprintf(file, "Blah.");

+0

謝謝。那麼,fprintf是可重定向的printf?而且,printf如何知道它是默認的控制檯? – 2010-05-13 15:57:37

+0

默認情況下,printf會轉到「stdout」引用的任何標準輸出。主要是控制檯,或者重定向(「yourprogram> output.txt」)重定向的文件。 – LukeN 2010-05-13 16:16:53

1

如果我的理解正確,聽起來好像您需要Windows API函數AttachConsole(pid),該函數將當前進程附加到PID爲pid的進程所擁有的控制檯。

+0

我認爲你是對的。 http://msdn.microsoft.com/en-us/library/ms681952%28VS.85%29.aspx – dss539 2010-05-12 21:37:24