65.9K
CodeProject 正在变化。 阅读更多。
Home

用于通过 keybd_event 和 CreateProcess 自动化简单计算机任务的类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.44/5 (9投票s)

2006年3月17日

7分钟阅读

viewsIcon

56128

downloadIcon

969

此类使用 keybd_event 和 CreateProcess 来创建一个脚本处理器和执行器。该脚本可用于自动化日常任务,例如打开和检查邮件帐户,自动化软件功能等。此功能适用于任何可以通过键盘输入内容的应用程序。

Sample Image - Sendkeys.jpg

引言

Windows 的 keybd_event 机制在许多方面都很有用,尤其是在自动化输入等任务方面。但它的能力受到限制,因为输入大量可能可变且不易编程的组合键可能会有些麻烦。所以我已经为你做好了所有繁重的工作。你只需将我提供的类包含在你的程序中,然后就可以创建一个脚本并使用类的成员函数来运行脚本。此脚本可用于自动化任何可以使用键盘完成的任务。如果你和我一样懒,这可能是一个福音。此外,CreateProcess 方法用于创建新进程,如 Winamp、IE 等。

基本的 keybd_event 和 CreateProcess

根据 MSDN 的说法,keybd_event 函数模拟击键。系统可以使用这种模拟的击键来生成 WM_KEYUPWM_KEYDOWN 消息。键盘驱动程序的中断处理程序会调用 keybd_event 函数。例如,如果要模拟按下 Enter 键,那么你需要使用 keybd_event 按下一次按键,然后再按一次释放按键,如下面的示例所示。

keybd_event(VK_RETURN, 0, 0, 0);
::Sleep(50);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);

为了模拟按下 ALT+ENTER 这样的组合键,你需要先按下 ALT,然后按下 ENTER,接着释放 ENTER,最后释放 ALT,如下所示。

keybd_event(VK_MENU, 0, 0, 0);
::Sleep(50);
keybd_event(VK_RETURN, 0, 0, 0);
::Sleep(50);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
::Sleep(50);
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);

VK_MENUVK_RETURN 分别是 ALT 和 ENTER 键的代码。你可以使用相应的十六进制值代替虚拟键码。官方的键及其代码表可以在 这里 找到。

CreateProcess 可通过将其可执行文件作为参数来创建新应用程序或进程。其用法如下所示,该示例打开一个新的记事本窗口。

TCHAR szCmdline[]=TEXT("notepad");

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi) );

// Start the child process. 
CreateProcess( NULL,   // No module name (use command line)
    szCmdline,      // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi ) ;          // Pointer to PROCESS_INFORMATION structure

创建进程后,如果你想向它传递任何键盘输入,你必须首先将焦点设置到新创建的进程上。这可以通过使用 SetFocus 函数完成,该函数需要 HWnd 作为参数。新创建进程的句柄可以从进程 ID 获取,方法是枚举 Windows。这里提供了一个很好的实现类:这里,因此你可以使用下面的代码在创建应用程序后将焦点设置到窗口上。

DWORD pid = pi.dwProcessId;
CMainWindowIterator itw(pid);
for (HWND hwnd = itw.First(); hwnd; hwnd=itw.Next())
{
    SetFocus(hwnd);
    break;
}

基本按键操作

现在,假设你想模拟按键。你只需使用 RunKey() 函数,如下所示。

VirKey vk; 
com="do";arg="TAB";times=2;sleep=300;

vk.RunKey(com,arg,times,sleep);

此函数调用将按下(或者更准确地说,模拟按下)TAB 键两次,间隔为 300 毫秒。com 参数(字符字符串)表示你要执行的命令。目前实现了两种命令:“do”和“open”。do 可用于输入任何组合键。“open”可用于打开任何应用程序。

现在,arg 参数(字符字符串)与 com 对应。如果 comdo,则 arg 包含特定键的代码,例如 TAB(支持的所有键及其代码的计数在源代码和二进制发行版中的 codes.txt 文件中给出)。如果 comopen,则 arg 是一个包含要创建的应用程序可执行文件的完整路径名的字符字符串,例如,对于 IE,默认值应为“C:\Program Files\Internet Explorer\IEXPLORE.EXE”。如果你的路径中包含空格(如上例所示),则必须确保你的路径用双引号括起来,因为这会直接传递给 CreateProcess 方法。times(整数)指定 doopen 命令必须执行的次数,而 sleep(整数)表示连续命令之间的时间(以毫秒为单位)。

将字符串转换为一系列按键

现在,如果你想将字符串作为一系列按键发送,并且认为上一个函数也很麻烦,那么本节可能会让你感兴趣。如果你的应用程序需要输入特定的单词,则可以使用 Runstring() 函数,如下所示。

VirKey vk;
vk.Runstring("Hello You!!!");

整个字符串将被转换为按键。注意:字符串函数只能处理标准字符,不能处理 TAB、ALT 等特殊键。

制作脚本

现在,这是真正乐趣开始的地方。如果你有大量任务或按键操作需要执行,则可以使用脚本功能。让我们先讨论脚本。脚本是顺序性的,并且语法简单。脚本中的每一行都有四个部分,与 RunKey() 的参数类似:commandargumenttimessleep。此处需要注意的细节是 argument 必须以 $ 结尾。例如,要打开 Internet Explorer,然后按 Enter,你的脚本将如下所示。

open "C:\Program Files\Internet Explorer\IEXPLORE.EXE"$ 1 4000 
do  RETURN$  1  200

除了常规命令 opendo 之外,还添加了一个名为 string 的附加命令。它可用于输入字符串。

string Hello!!$ 1 100

现在,当你的脚本准备好后,你必须对其进行处理,生成一个包含十六进制代码而不是按键代码的文件。此文件将在运行时加载、解释和运行。这可以节省运行时的时间和资源,类似于编译和执行。要处理给定的脚本文件,可以使用 ES2S() 函数。此函数接受两个参数(字符字符串):源脚本文件名和脚本名称。例如,要从 Scriptfile.txt 准备名为 hello 的脚本,函数调用如下:

VirKey vk;
vk.ES2S("Scriptfile.txt","hello");

现在,如果你的脚本准备好了,你可能会急于运行它,在这种情况下,你必须使用 Runx() 函数,它接受脚本名称作为参数。因此:

VirKey vk;
vk.Runx("hello");

复合按键

你的应用程序可能需要处理复合按键组合,如 ALT+F4。为此,已支持 ALT、SHIFT、CTRL 和 WIN 的复合按键。因此,你只需在 RunKey 函数或脚本中将 ALT+F4 输入为 arg

注意:如果你计划使用 2-3 个复合组合键,例如 SHIFT+CTRL+DEL,那么最好按照 ALT、CTRL、SHIFT、WIN 的顺序进行。例如 ALT+CTRL+f 或 CTRL+SHIFT+C 等。你应该明白这个意思。

Application

已提供了一个示例应用程序作为演示。使用该应用程序非常简单。首先,你必须准备一个要运行的脚本。假设你想打开一个 Internet Explorer 窗口,然后自动打开 Yahoo! 邮件并登录你的帐户。然后,如果你没有设置主页,并且在访问 Internet 时没有代理身份验证,你的脚本应该如下所示。

open "C:\Program Files\Internet Explorer\IEXPLORE.EXE"$ 1 4000 
do TAB$ 1 200
string http://mail.yahoo.com$ 1 1000
do RETURN$ 1 4000
string username$ 1 100
do TAB$ 1 100
string password$ 1 100
do RETURN$ 1 200

准备好脚本后,将其保存在文件中,然后打开上面提供的应用程序。单击“New Script File”(新建脚本文件)。将出现一个文件打开对话框。选择你的脚本文件,然后输入你想要运行脚本的名称,例如“login”。然后,按“Make Script”(制作脚本);你的脚本将被处理。然后,在第一个编辑器中输入你为脚本提供的名称,例如“login”,然后单击“Execute”(执行)。然后,请不要触摸键盘或鼠标,脚本将开始执行,打开一个 IE 窗口,打开 Yahoo!,然后登录。

结论

总之,如果你想将此类集成到你的应用程序中,只需将 Virkey.cppVirKey.hWindowIterator.cppWindowIterator.h 添加到你的代码中即可。我想感谢 Paul DiLascia 使用他的类来从进程 ID 获取进程句柄,并且我想为我在英语语言上犯下的非人道的暴行表示诚挚的歉意。如果你觉得这个类有用,请随时通过我的电子邮件地址提出你的问题、建议、遇到的问题和 bug;否则,如果你只能想到对我进行诅咒,那么我也可以寻找写这篇文章的那个白痴。

© . All rights reserved.