我正在尝试将命令发送到a的输入cmd.exe
使用低级读/写控制台功能的应用程序。我使用以下命令阅读文本(抓取)没有任何问题ReadConsole...()
and 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
to STD_INPUT_HANDLE
。如果我写信给(STD_OUTPUT_HANDLE)
我确实得到了我的dir
写在屏幕上,但当然什么也没有发生。我正在猜测SetConsoleMode()
可能有帮助,但我尝试了很多模式组合,但没有任何帮助。我还创建了一个等待输入的快速控制台应用程序(scanf()
)并回显无论进入的内容,都不起作用。
我也尝试过输入scanf()
提示,然后使用查看输入缓冲区PeekConsoleInput()
,返回 0,但是INPUT_RECORD
数组为空。
我知道还有另一种方法可以使用WriteConsoleInput()
直接将 INPUT_RECORD 结构化事件注入控制台,但这太长了,我必须将每个按键发送到其中。
我希望问题很清楚。如果您需要任何进一步的信息,请告诉我。感谢您的帮助。
更新1:
我能够将按键发送到cmd
过程使用WriteConsoleInput()
with INPUT_RECORD
然而,结构AttachConsole
有时会抛出ERROR_GEN_FAILURE #31: A device attached to the system is not functioning.
,因此INPUT_RECORD
未发送(Error 6: Invalid Handle
). Sleep(1000)
after CreateProcess()
before AttachConsole()
解决了这个问题。那些角色dir
自动输入,但我不知道如何发送RETURN
key:
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()
to ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT
以及它们的组合,但没有结果。但是,如果我按键盘上的 Enter 键,则会自动输入dir
命令执行(与我刚刚执行的时候不同)WriteConsole()
),所以我想我走在正确的轨道上。
SSH 不会发送实际的按键并获取实际的屏幕缓冲区(如 TAB 和 CTRL+C CTRL+D 工作)吗?我正在寻找类似的东西。
更新2:
我发现注入 return 命令的问题。本来应该ir[1].Event.KeyEvent.uChar.AsciiChar = '\r';
即一个\r
代替\n
,超级简单。
好像没有办法使用WriteConsole()
要输入命令,应该通过发送WriteConsoleInput()
INPUT_RECORD 或通过创建管道(这并不总是完美的,但对于大多数直接的应用程序来说非常有用)。使用的一大优点WriteConsoleInput()
是你可以发送的VK_UP
and VK_DOWN
,访问控制台历史记录(如果我们在 CMD 中)并且VK_TAB
对于自动完成,所有 CTRL+_ 序列、ESC 和功能键,甚至鼠标单击。
更多信息请点击这里:http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx这里还有大量的例子:
如果有人有其他好主意,请随时参与。感谢所有对此感兴趣的人。希望这对将来的人有帮助。