Windows — наследовать дескриптор файла консоли в дочернем процессе

У меня есть приложение для 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), ...), Например, это работает для текстового файла. Но это не работает для дескриптора консоли.

Что я делаю не так?

0

Решение

Да, arx (см. Комментарии выше) абсолютно прав: дескриптор файла консоли является «поддельным» дескриптором, так как он не существует на уровне ОС (и не может быть унаследован). Этот тип дескриптора файла известен только для библиотек API Win32 (kernel32.dll) и запросов ввода-вывода, обрабатываемых только на этом уровне. Windows не имеет реальных файлов консоли, как виртуальные терминалы в Unix (кроме Windows8). 🙁 Итак, мне нужно изменить подсистему моего приложения с типа «windows» на «console», и тогда приложение может использовать предварительно выделенную консоль (но дескриптор файла все еще не может быть унаследован — необходимо повторно открыть «CONOUT $» в дочернем процессе …)

0

Другие решения


По вопросам рекламы [email protected]