Как WriteConsoleInput дочернему приложению, ожидающему в ReadConsoleInput?

Поэтому я пытался читать и писать из Pianobar (консольный плеер Pandora) STDIN и STDOUT, чтобы управлять им из другого приложения.

Тем не менее, для некоторых при чтении из STDOUT он полностью блокируется в последней строке (где он отображает время песни).

Я думал, что делал что-то не так (вероятно, все еще), но я скачал демонстрационный проект для отправки / получения входных данных в другие приложения STDIN / STDOUT через пару дескрипторов.

Итак, я углубился в код Pianobar и вставил команды printf повсеместно, чтобы отследить, где происходил блок (это правильное слово для блока?). В любом случае, я, наконец, попадаю в раздел кода, который, кажется, зацикливается очень быстро, когда создается как дочерний процесс, а также блокирует STDOUT.

От Pianobar, замена ui_readline.c BarReadline

/*  readline replacement
*  @param buffer
*  @param buffer size
*  @param accept these characters
*  @param input fds
*  @param flags
*  @param timeout (seconds) or -1 (no timeout)
*  @return number of bytes read from stdin
*/
size_t BarReadline (char *buf, const size_t bufSize, const char *mask,
BarReadlineFds_t *input, const BarReadlineFlags_t flags, int timeout)
{
// took out some extra code from here ...
printf("In BarReadline 005\n");
fflush(stdout);
while (true) {
Sleep(400); // added this to stop it from doing 100% on a core
printf("In BarReadline 006\n");
fflush(stdout);
if (timeout != INFINITE) {
DWORD now = GetTickCount ();
printf("In BarReadline 007\n");
fflush(stdout);
if ((int)(now - timeStamp) < timeout) {
timeout -= (int)(now - timeStamp);
timeStamp = now;
}
else
timeout = 150; // KYLE changed from 0
}
printf("Current timeout: %d\n",timeout);
printf("In BarReadline 008\n");
fflush(stdout);
waitResult = WaitForSingleObject (handle, timeout);

printf("In BarReadline 009\n");
fflush(stdout);
if (WAIT_OBJECT_0 == waitResult) {
INPUT_RECORD inputRecords[8];
INPUT_RECORD* record;
DWORD recordsRead, i;

printf("In BarReadline 010\n");
fflush(stdout);
successConsole = ReadConsoleInput (handle, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &recordsRead);
if(successConsole != 0) {
printf("We read from console\n");
}

printf("In BarReadline 011\n");
fflush(stdout);
for (i = 0, record = inputRecords; i < recordsRead; ++i, ++record) {
int codePoint, keyCode;

printf("In BarReadline 012\n");
fflush(stdout);

И код выше распечатывает:

In BarReadLine 005
In BarReadline 006
In BarReadline 007
Current timeout: 150
In BarReadline 008
In BarReadline 009
In BarReadline 010
In BarReadline 011
In BarReadline 006
In BarReadline 007
Current timeout: 150
In BarReadline 008
In BarReadline 009
In BarReadline 010
In BarReadline 011

В любом случае, я могу нажать клавишу «ввод» в демонстрационном приложении Redirect с помощью известного ключа, который не требует ничего особенного, он просто продолжает вращаться в этом цикле и, кажется, не перехватывает его, что для меня звучит как один из две вещи; У нас нет доступа к функции INPUT, так как она блокируется чтением STDOUT, или ReadConsoleInput не распознает то, что мы отправляем из демонстрации Redirect.

Это то, что мне нужно отправить с каким-либо типом асинхронного процесса ввода-вывода? И почему использование «cmd» и открытие обычной командной строки не вызывает блокировку, но это делает?

Обновление 1: Мне удалось построить INPUT_RECORD для отправки на ReadConsoleInput в Pianobar (дочерняя консоль). Тем не менее, я обнаружил, что мое родительское приложение возвращает «неверный дескриптор», когда я пытаюсь отправить WriteConsoleInput(m_hStdinWrite, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &dwWritten);

Существуют ли разные виды ручек для детской консоли STDIN? Использование WriteFile работает, но я не могу отправить INPUT_RECORDs таким образом.

Redirect Demo App

Pianobar Windows Binaries

Pianobar Windows Build Environment

Помогло, но не уверен, что вызывает неправильный дескриптор:
Низкоуровневый ввод и перенаправление консоли

0

Решение

Я считаю, что это потому, что программа использует ReadConsoleInput вместо ReadFile. ReadConsoleInput требует дескриптор консоли.

Вам нужно будет создать консоль и передать ее дескриптор. Тогда вам нужно будет записать в него события ввода с консоли.

Было бы лучше, если бы вы могли изменить другую программу, чтобы она просто использовала ReadFile, если бы вы могли заставить это работать.

Похоже, это ссылка на MSDN для консолей.

1

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

Других решений пока нет …

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