簡體   English   中英

如何在不調用 AllocConsole() 的情況下在 subsystem=windows 程序中初始化 stdout/stderr?

[英]How to initialize stdout/stderr in a subsystem=windows program WITHOUT calling AllocConsole()?

因此,當嘗試在 Windows GUI 應用程序中使用 stdin/stdout/stderr 流時,通常必須調用 AllocConsole(或 AttachConsole)以初始化這些流以供使用。 這里有很多關於調用 AllocConsole 后需要做什么的帖子(即在各自的流上使用 freopen_s 等)。

我有一個程序,我想將 stdout 和 stderr 重定向到匿名管道。 我有一個工作示例,我稱之為:

    AllocConsole();

    FILE* fout;
    FILE* ferr;

    freopen_s(&fout, "CONOUT$", "r+", stdout);
    freopen_s(&ferr, "CONOUT$", "r+", stderr);

    HANDLE hreadout;
    HANDLE hwriteout;
    HANDLE hreaderr;
    HANDLE hwriteerr;

    SECURITY_ATTRIBUTES sao = { sizeof(sao),NULL,TRUE };
    SECURITY_ATTRIBUTES sae = { sizeof(sae),NULL,TRUE };
    CreatePipe(&hreadout, &hwriteout, &sao, 0);
    CreatePipe(&hreaderr, &hwriteerr, &sae, 0);

    SetStdHandle(STD_OUTPUT_HANDLE, hwriteout);
    SetStdHandle(STD_ERROR_HANDLE, hwriteerr);

此代碼段成功地將 stdout 和 stderr 設置為匿名管道的寫入端,我可以捕獲數據。

然而,調用 AllocConsole 將產生一個 Conhost.exe - 這是彈出到屏幕的實際黑色窗口。 我對此沒有用處,最重要的是,我想避免在我的程序下創建子 conhost.exe 的進程。

所以問題是,我怎樣才能讓 Windows 認為它連接了一個控制台/手動設置初始 stdout 和 stderr 文件流,以便我可以像我已經完成的那樣重定向它們? 我查看了調試器中的 AllocConsole 調用以及 GetStdHandle 和 SetStdHandle 以嘗試了解正在發生的事情,但我缺乏 RE 技能。

如果沒有 AllocConsole,freopen_s 調用將失敗並顯示錯誤 6,句柄無效。 GetStdHandle 也返回一個 NULL 句柄。 調用 SetStdHandle 成功(基於它的返回代碼和調用 GetLastError),但這似乎並沒有真正在我需要的地方設置東西,因為我沒有在我的管道中收到任何輸出。

有任何想法嗎?

使用 SetStdHandle 函數將管道 HANDLE 值分配給 STD_INPUT_HANDLE 和 STD_OUTPUT_HANDLE。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM