Я пытаюсь отправить команды на вход приложения 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()
, а затемзаглянуть во входной буфер, используя 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()
), так что я думаю, что я на правильном пути.
Не работаетt 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
Если у кого-то есть другие отличные идеи, не стесняйтесь делать этов. Спасибо всем, кто заинтересовался этим.Надеюсь, это поможет кому-то в будущем.