Низкоуровневый ввод с консоли и перенаправление

Я пытаюсь отправить команды на вход приложения 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 .

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

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

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

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

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

Я могу отправлять нажатия клавиш процессу cmd , используя WriteConsoleInput () со структурами INPUT_RECORD , однако AttachConsole иногда выдает ERROR_GEN_FAILURE # 31: устройство, подключенное к системе, не работает. , и поэтому INPUT_RECORD не отправляются ( Ошибка 6: недопустимый дескриптор ). 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 () ), поэтому я думаю, что я прав трек.

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

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

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

Похоже, что нет способа использовать WriteConsole () для ввода команд, нужно обойтись путем отправки WriteConsoleInput () INPUT_RECORD или путем создания каналов (которые являются не всегда идеально, но отлично подходит для большинства простых приложений). Одним из больших преимуществ использования WriteConsoleInput () является то, что вы можете отправить VK_UP и VK_DOWN для доступа к истории консоли (если мы ' плюс тонны примеров здесь: http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366

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

6
задан 13 revs 17 January 2011 в 16:18
поделиться