2014-11-15 60 views
0

我有一個Windows應用程序(subsystem=windows,不是控制檯應用程序)。我在該應用程序中創建一個控制檯,然後創建一個子進程。當我創建控制檯時,我使控制檯文件句柄可繼承(請參見下文)。當我創建子進程時,我將參數CreateProcess設置爲TRUE。我希望孩子進程能夠讀取和寫入控制檯,但我得到錯誤0x06,invalid handleWindows - 在子進程中繼承控制檯文件句柄

我執行以下操作:

1)AllocConsole();

2)CreateFile("CONIN$", ...)CreateFile("CONOUT$", ...)CreateConsoleScreenBuffer(...)具有以下SetConsoleActiveScreenBuffer(...)。總是有SecurityAttributesbInheritHandle=TRUE。 ,但請參閱bInheritHandle=1

3)CreateProcess(NULL, GetCommandLine(), NULL, NULL, TRUE, /* inherit handles */ 0, NULL, NULL, &sinfo, &child);

在子過程:

1)_open_osfhandle((intptr_t)console_handle, 0)給我-1GetLastError()返回錯誤0x06 - "Invalid handle"

子進程是其父進程的副本,因此兩個進程都有相同的子系統:windows(不是控制檯應用程序)。

我檢查過其他文件句柄是否正常繼承,可以與fdopen(_open_osfhandle(file_handle), ...)一起使用。例如,它適用於文本文件。但它不適用於控制檯句柄。

我做錯了什麼?

+0

不清楚你在第2步中做了什麼,或者子進程從中獲取'console_handle'的值,請顯示一些實際的代碼 –

+1

控制檯句柄是引用的僞句柄到當前進程的控制檯,如果子進程是一個Windows應用程序,那麼啓動它時將不會有控制檯,所以引用當前控制檯的句柄是無意義的。 – arx

+0

您是否在父prog中調用了'SetStdHandle()' ?看到這個繼承兒童gui的控制檯http://hg.netbeans.org/main-golden/file/2da7b1f9de9b/onbootstrap/launcher/windows/utilsfuncs.cpp#l343 – basin

回答

0

是的,arx(請參閱上面的註釋)絕對正確:控制檯文件句柄是「假」句柄,因爲它不存在於操作系統級別(並且不能被繼承)。這種類型的文件句柄僅爲Win32 api庫(kernel32.dll)和僅在此級別處理的I/O請求所知。 Windows沒有真正的控制檯文件,就像Unix中的虛擬終端(Windows8除外)。 :-(所以,我需要將我的應用程序的子系統從「windows」類型更改爲「控制檯」,然後應用程序可以使用預分配的控制檯(但文件句柄仍然不能被繼承 - 需要重新打開「CONOUT $」在子進程中......)