是否有可能以某種方式更改Windows上的標準I/O功能句柄?提供的語言是C++。如果我理解正確,通過選擇控制檯項目,編譯器只需爲您預先分配控制檯,並操作所有標準I/O函數以處理其句柄。所以,我想要做的是讓一個控制檯應用程序實際寫入另一個應用程序控制臺緩衝區。雖然我可以獲得第一個控制檯句柄,但是通過文件將其傳遞給第二個應用程序(我不太瞭解進程間通信,而且這看起來很簡單),並且以某種方式用於第一個應用程序句柄的prinf。這可以做到嗎?我知道如何獲得控制檯句柄,但我不知道如何將printf重定向到該句柄。它只是爲了學習目的而更加了解OS背後的工作。我感興趣的是printf如何知道它所控制的控制檯。更改默認控制檯I/O功能句柄
回答
如果我理解你正確,你可以在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)。
如果你想printf
重定向到一個手柄(FILE *),只是做
fprintf(handle, "...");
例如複製printf
與fprintf
fprintf(stdout, "...");
或錯誤報告
fprintf(stderr, "FATAL: %s fails", "smurf");
這也是你寫入文件的方式。 fprintf(file, "Blah.");
如果我的理解正確,聽起來好像您需要Windows API函數AttachConsole(pid)
,該函數將當前進程附加到PID爲pid
的進程所擁有的控制檯。
我認爲你是對的。 http://msdn.microsoft.com/en-us/library/ms681952%28VS.85%29.aspx – dss539 2010-05-12 21:37:24
- 1. 獲取控制檯句柄
- 2. 更改默認功能django
- 3. 更改默認控制器
- 4. web2py:更改默認控制器和功能
- 5. 更改功能之前的默認值
- 6. 更改dropzone.js的默認功能性
- 7. Android開發者控制檯,更改默認語言
- 8. 如何更改默認的Eclipse控制檯?
- 9. 如何更改代碼::塊默認控制檯
- 10. AWS管理控制檯 - 從S3更改默認值?
- 11. 啓動期間更改默認控制檯日誌級別
- 12. 更改控制檯應用程序的默認設置
- 13. 更改Laravel的默認(根)控制器
- 14. 更改默認控制器actionresult
- 15. Yii 2.0更改默認控制器
- 16. 在功能區控件上更改默認語言
- 17. 使用Symfony2 Doctrine2控制檯/生成功能更改表格?
- 18. dataGridView默認錯誤對話框句柄
- 19. Rails的控制檯默認環境
- 20. 更改默認scala平臺netbeans?
- 21. 更改gtk.Paar句柄大小
- 22. 更改控制檯大小
- 23. Javascript默認功能
- 24. 默認功能 - PHP
- 25. 默認複製構造函數句柄const?
- 26. 如何更改Symfony2 Behat Bundle默認功能上下文文件(FeatureContext.php默認)
- 27. 是否有可能取代Eclipse中的默認控制檯?
- 28. 如何更改Firebase控制檯網頁中的語言默認值?
- 29. 限制(amp)功能的默認參數
- 30. CakePHP默認控制器不改變URL
謝謝。那麼,fprintf是可重定向的printf?而且,printf如何知道它是默認的控制檯? – 2010-05-13 15:57:37
默認情況下,printf會轉到「stdout」引用的任何標準輸出。主要是控制檯,或者重定向(「yourprogram> output.txt」)重定向的文件。 – LukeN 2010-05-13 16:16:53