У меня есть приложение для Windows (subsystem=windows
, а не консольное приложение). Я создаю консоль в этом приложении, а затем создаю дочерний процесс. Когда я создаю консоль, я делаю дескриптор файла консоли наследуемым (см. Ниже). Когда я создаю дочерний процесс, я устанавливаю bInheritHandles
аргумент CreateProcess
в TRUE
, Я хочу, чтобы дочерний процесс мог читать и писать с консоли, но я получаю сообщение об ошибке 0x06
, invalid handle
,
Я делаю следующее:
1) AllocConsole();
2) CreateFile("CONIN$", ...)
, CreateFile("CONOUT$", ...)
или же
CreateConsoleScreenBuffer(...)
со следующим SetConsoleActiveScreenBuffer(...)
, Всегда иметь SecurityAttributes
с bInheritHandle=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)
дает мне -1
а также GetLastError()
возвращает ошибку 0x06
— "Invalid handle"
,
Дочерний процесс является копией своего родителя, поэтому оба процесса имеют одну подсистему: windows
(не консольное приложение).
Я проверил, что другие файловые дескрипторы наследуются нормально и могут использоваться с fdopen(_open_osfhandle(file_handle), ...)
, Например, это работает для текстового файла. Но это не работает для дескриптора консоли.
Что я делаю не так?
Да, arx (см. Комментарии выше) абсолютно прав: дескриптор файла консоли является «поддельным» дескриптором, так как он не существует на уровне ОС (и не может быть унаследован). Этот тип дескриптора файла известен только для библиотек API Win32 (kernel32.dll) и запросов ввода-вывода, обрабатываемых только на этом уровне. Windows не имеет реальных файлов консоли, как виртуальные терминалы в Unix (кроме Windows8). 🙁 Итак, мне нужно изменить подсистему моего приложения с типа «windows» на «console», и тогда приложение может использовать предварительно выделенную консоль (но дескриптор файла все еще не может быть унаследован — необходимо повторно открыть «CONOUT $» в дочернем процессе …)