процесс, без проблем и без труб, насколько я вижу.

аюсь отправить команды на входcmd.exe приложение с использованием низкоуровневых консольных функций чтения / записи. У меня нет проблем с чтением текста (соскоб) с помощьюReadConsole...() а такжеWriteConsole() функции после подключения к консоли процесса, но я не понял, например, как писать"dir" и консоль должна интерпретировать ее как отправленную команду.

Вот немного моего кода:

CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
AttachConsole(pi.dwProcessId);

strcpy(buffer, "dir");
WriteConsole(GetStdHandle(STD_INPUT_HANDLE), buffer, strlen(buffer), &charRead, NULL);

STARTUPINFO атрибуты процесса все установлены на ноль, кроме, конечно,.cb приписывать.

На экране ничего не меняется, однако я получаюError 6: Invalid Handle вернулся изWriteConsole вSTD_INPUT_HANDLE, Если я напишу(STD_OUTPUT_HANDLE) Я понимаюdir написано на экране, но ничего, конечно, не происходит. я догадываюсьSetConsoleMode() может быть полезно, но я пробовал много комбинаций режимов, ничего не помогло. Я также создал быстрое консольное приложение, которое ждет ввода (scanf()) и повторяет все, что входит, не сработало.

Я также попытался ввести вscanf() Promp, а затем заглянуть в буфер ввода с помощьюPeekConsoleInput(), возвращает 0, ноINPUT_RECORD массив пуст

Я знаю, что есть другой способ обойти этоWriteConsoleInput() напрямую вводить структурированные события INPUT_RECORD в консоль, но это будет слишком долго, мне придется отправлять каждое нажатие на нее.

Я надеюсь, что вопрос ясен. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация. Спасибо за вашу помощь.

Обновление 1:

Я могу отправить нажатия клавишcmd процесс с использованиемWriteConsoleInput() с участиемINPUT_RECORD структуры, однако,AttachConsole иногда бросаетERROR_GEN_FAILURE #31: A device attached to the system is not functioning.и, таким образом,INPUT_RECORD не отправляются (Error 6: Invalid Handle).Sleep(1000) послеCreateProcess() доAttachConsole() решает это. Персонажиdir вводятся автоматически, но я не могу понять, как отправитьRETURN ключ:

ir[0].EventType = KEY_EVENT;
ir[0].Event.KeyEvent.bKeyDown = TRUE;
ir[0].Event.KeyEvent.dwControlKeyState = 0;
ir[0].Event.KeyEvent.uChar.UnicodeChar = '\n';
ir[0].Event.KeyEvent.wRepeatCount = 1;
ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
ir[1].EventType = KEY_EVENT;
ir[1].Event.KeyEvent.bKeyDown = FALSE;
ir[1].Event.KeyEvent.dwControlKeyState = 0;
ir[1].Event.KeyEvent.uChar.UnicodeChar = '\n';
ir[1].Event.KeyEvent.wRepeatCount = 1;
ir[1].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir[1].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);

WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, &charRead);

WriteConsoleInput возвращается0, но в консоли ничего не происходит, я попытался установитьSetConsoleMode() вENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT и их комбинация, но без результатов. Однако, если я нажимаю клавишу ввода с клавиатуры, автоматически набираетсяdir команда выполняется (в отличие от тех времен, когда я простоWriteConsole()), так что я думаю, что я на правильном пути.

Разве SSH не отправляет поверх фактических нажатий клавиш и получает фактический экранный буфер (как TAB, и CTRL + C, CTRL + D работают)? Я после чего-то в этом роде.

Обновление 2:

Я обнаружил проблему с введением команды возврата. Должно былоir[1].Event.KeyEvent.uChar.AsciiChar = '\r'; то есть\r вместо\nсупер просто.

Кажется, что нет никакого способа использованияWriteConsole() вводить команды нужно, отправивWriteConsoleInput() INPUT_RECORDs или путем создания каналов (которые не всегда идеальны, но отлично подходят для большинства простых приложений). Одно большое преимущество использованияWriteConsoleInput() это то, что вы можете отправитьVK_UP а такжеVK_DOWN, чтобы получить доступ к истории консоли, (если мы в CMD) иVK_TAB для автозаполнения - все последовательности CTRL + _, клавиши ESC и FUNCTION и даже щелчки мышью.

Больше информации здесь:http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx плюс тонны примеров здесь:http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366

Если у кого-то есть другие замечательные идеи, не стесняйтесь вносить. Спасибо всем, кто заинтересовался этим. Надеюсь, это поможет кому-то в будущем.

Ответы на вопрос(1)

тного ввода, а не в процесс cmd.exe. Вам придется проделать гораздо больше работы, чтобы перенаправить дескриптор ввода для этого. Требуется труба. ВотСтатья кб это показывает шаблонный код.

Btw:всегда проверьте возвращаемое значение функций API.

 soulseekah17 янв. 2011 г., 11:45
Я могу попытаться использовать канал для прямого ввода в порожденный процесс, как в КБ, а затем прочитать его буфер вывода консоли, подключившись к нему, потому чтоstdout не содержит всех данных, напечатанных на экране. Видетьstackoverflow.com/questions/2537180/...
 Hans Passant17 янв. 2011 г., 11:33
Вы только разделяете окно консоли, вот и все. Да, код ошибки показывает, что происходит не так, вы не можете записать в дескриптор ввода.
 soulseekah17 янв. 2011 г., 11:29
Я думал, что я подключен к консоли нового процесса.AttachConsole() позволяет это; когда яprintf() после прикрепления я на самом деле печатаю вcmd.exe, Я обновил код ошибки, полученный отWriteConsole() вSTD_INPUT_HANDLE
 soulseekah17 янв. 2011 г., 11:37
Я прочитал этот код и попробовал его вчера, работает как шарм, увы такие порожденные программы, какFTP.exe а такжеEDIT.exe иметь свои собственные буферы, которые не перенаправляются, это требует низкоуровневого чтения и записи в консоль. По сути, я хочу клонировать окно консоли, перенаправляя все с одного на другое.
 soulseekah17 янв. 2011 г., 11:55
Добавление сообщества вmsdn.microsoft.com/en-us/library/ms687403%28VS.85%29.aspx WriteConsoleInput() показывает, как отправить ключи с помощьюINPUT_RECORD s, чтобы отправить выводsystem("edit") процесс, без проблем и без труб, насколько я вижу.

Ваш ответ на вопрос