C 通过 PID 以编程方式将 Enter 发送到 cmd.exe
C Programatically send Enter to cmd.exe by PID
目标是以编程方式按 Enter 进入某些 cmd.exe(运行 在后台,例如由 SYSTEM 用户拥有,从 windows 服务启动)这将在视觉上导致新的空提示行,如“C:\dev\sendenter>”。
我在网上找到的所有内容都集中在接收密钥上,您可以在其中选择检查是否发送了 ascii 代码 10 或 13。但是当将它们发送到 运行 cmd.exe 时,所发生的只是你得到一个换行符但没有新的命令提示符。即使使用 VK_RETURN 应该是 Carriage Return 的别名,换行符也不会以新提示结束。
我认为问题可能是 WM_KEYUP 或类似的必须遵循 ASCII 键 10 或 13,但我无法使用下面的最小示例找出如何发送它。
#include <Windows.h>
#include <stdio.h>
//argument: int PID of process
//compile with gcc, no options
//first and only argument: int PID
int main(int argc, char** argv){
DWORD pid = atoi(argv[1]);
printf ("Argument PID: %d\n",pid);
if (!FreeConsole())
{
printf("Could not FreeConsole\n");
exit(1);
}
if (!AttachConsole(pid)){
printf("Error: could not attach console to specified PID\n");
exit(2);
}
char s[] = {VK_RETURN};
HANDLE stdoutt = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned long cChars;
WriteConsole(stdoutt, s, lstrlen(s), &cChars, NULL);
return 0;
}
在 VS 2013 上测试
int main(int argc, char** argv){
DWORD pid = atoi(argv[1]);
if (!FreeConsole())
{
printf("Could not FreeConsole\n");
exit(1);
}
if (!AttachConsole(pid)){
printf("Error: could not attach console to specified PID\n");
exit(2);
}
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD ir[2];
DWORD dwTmp = 0;
ir[0].EventType = KEY_EVENT;
ir[0].Event.KeyEvent.bKeyDown = TRUE;
ir[0].Event.KeyEvent.dwControlKeyState = 0;
ir[0].Event.KeyEvent.uChar.UnicodeChar = '\r';
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 = '\r';
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(hConsole, ir, 2, &dwTmp); // <-- 2 it's the number of inputs to send
return 0;
}
我只测试了 cmd.exe
打开并向该进程发送输入,一开始它只在控制台中输入 ?
,那是因为你必须发送两个输入,第一个是bKeyDown
到 TRUE
以及后来的 FALSE
和 UnicodeChar
设置为 \r
而不是 \n
我还必须将 wRepeatCount
设置为 1
因为它会触发断言
微软says:
wRepeatCount
The repeat count, which indicates that a key is being held down. For
example, when a key is held down, you might get five events with this
member equal to 1, one event with this member equal to 5, or multiple
events with this member greater than or equal to 1.
请记住,任何 printf
都将被发送到连接的控制台并且可能会弄乱输入
目标是以编程方式按 Enter 进入某些 cmd.exe(运行 在后台,例如由 SYSTEM 用户拥有,从 windows 服务启动)这将在视觉上导致新的空提示行,如“C:\dev\sendenter>”。
我在网上找到的所有内容都集中在接收密钥上,您可以在其中选择检查是否发送了 ascii 代码 10 或 13。但是当将它们发送到 运行 cmd.exe 时,所发生的只是你得到一个换行符但没有新的命令提示符。即使使用 VK_RETURN 应该是 Carriage Return 的别名,换行符也不会以新提示结束。
我认为问题可能是 WM_KEYUP 或类似的必须遵循 ASCII 键 10 或 13,但我无法使用下面的最小示例找出如何发送它。
#include <Windows.h>
#include <stdio.h>
//argument: int PID of process
//compile with gcc, no options
//first and only argument: int PID
int main(int argc, char** argv){
DWORD pid = atoi(argv[1]);
printf ("Argument PID: %d\n",pid);
if (!FreeConsole())
{
printf("Could not FreeConsole\n");
exit(1);
}
if (!AttachConsole(pid)){
printf("Error: could not attach console to specified PID\n");
exit(2);
}
char s[] = {VK_RETURN};
HANDLE stdoutt = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned long cChars;
WriteConsole(stdoutt, s, lstrlen(s), &cChars, NULL);
return 0;
}
在 VS 2013 上测试
int main(int argc, char** argv){
DWORD pid = atoi(argv[1]);
if (!FreeConsole())
{
printf("Could not FreeConsole\n");
exit(1);
}
if (!AttachConsole(pid)){
printf("Error: could not attach console to specified PID\n");
exit(2);
}
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD ir[2];
DWORD dwTmp = 0;
ir[0].EventType = KEY_EVENT;
ir[0].Event.KeyEvent.bKeyDown = TRUE;
ir[0].Event.KeyEvent.dwControlKeyState = 0;
ir[0].Event.KeyEvent.uChar.UnicodeChar = '\r';
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 = '\r';
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(hConsole, ir, 2, &dwTmp); // <-- 2 it's the number of inputs to send
return 0;
}
我只测试了 cmd.exe
打开并向该进程发送输入,一开始它只在控制台中输入 ?
,那是因为你必须发送两个输入,第一个是bKeyDown
到 TRUE
以及后来的 FALSE
和 UnicodeChar
设置为 \r
而不是 \n
我还必须将 wRepeatCount
设置为 1
因为它会触发断言
微软says:
wRepeatCount
The repeat count, which indicates that a key is being held down. For example, when a key is held down, you might get five events with this member equal to 1, one event with this member equal to 5, or multiple events with this member greater than or equal to 1.
请记住,任何 printf
都将被发送到连接的控制台并且可能会弄乱输入