我目前正在编写一个简单的程序来使用 Firefox 的内置更新服务(从菜单 -> 帮助 -> 关于访问)自动更新 Firefox。我正在使用 ShellExecute 打开 Firefox,并使用 sendInput 将击键“Alt + h”和“a”发送到打开的 Firefox 窗口。我的代码目前在打开更新菜单时工作,但我正在使用系统睡眠方法调用来给 Firefox 在调用 sendInput 之前打开足够的时间。有什么方法可以让我检查 Firefox 是否已打开并准备好接收键盘输入(例如,较慢的机器需要 10 秒,而我的机器需要 1 秒)?我不确定 sendInput 是否有任何可以提供此功能的关联方法,而且我还无法在 MSDN 上找到有关此主题的任何信息。谢谢,
#include <Windows.h>
#include <exception>
const int ERROR_VALUE_RANGE = 32;
using namespace std;
//Method Declarations
void openProgram(char filePath[]);
void openUpdateMenu();
/**
* exception class for throwing ShellExecute Exceptions
* throws char* "Error opening program" if any issues arise
*/
class runException: public exception {
virtual const char* what() const throw() {
return "Error opening program";
}
} runEx;
int main (void) {
// Path to Mozilla Firefox
char filePath[] = "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe";
// Start Firefox using openProgram Method
try {
openProgram(filePath);
}
catch (exception& e) {
//Insert code to open dialog box displaying error message;
}
Sleep(5000); //sleep for one second while we wait for Windows Update to open
openUpdateMenu();
return 0;
}
/**
* method openProgram opens a file using the ShellExecute method
* @param filePath - a char array of the complete filepath
*/
void openProgram(char filePath[]) { // throws (runEx)
HINSTANCE exReturn = ShellExecute(
HWND_DESKTOP, // Parent is desktop
"open", // Opens file (explorer double click behavior)
filePath, // Path to Windows Update program
NULL, // Parameters
NULL, // Default Directory
SW_SHOW); // Show the program once it opens
//if there are any issues opening the file the return value will be less than 32
if ((int)exReturn <= ERROR_VALUE_RANGE) {
throw runEx; //throws runException
}
return;
}
/**
* method openUpdateMenu sends key commands to Firefox to open the about menu with the update service
*/
void openUpdateMenu() {
//set up keyboard emulation
INPUT Input; //declare input object
Input.type = INPUT_KEYBOARD;
Input.ki.time = 0; //let system provide timestamp
Input.ki.dwExtraInfo = 0;
//simulate pressing alt down
Input.ki.wVk = VK_LMENU;
Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
SendInput(1, &Input, sizeof(INPUT));
//simulate pressing 'h' down
Input.ki.wVk = 0x48;
Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
SendInput(1, &Input, sizeof(INPUT));
//release alt key
Input.ki.wVk = VK_LMENU;
Input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &Input, sizeof(INPUT));
//release 'h' key
Input.ki.wVk = 0x48;
Input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &Input, sizeof(INPUT));
Sleep(500); // wait for menu to open
//simulate pressing 'a' down
Input.ki.wVk = 0x41 ;
Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
SendInput(1, &Input, sizeof(INPUT));
//release 'a' key
Input.ki.wVk = 0x41 ;
Input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &Input, sizeof(INPUT));
//wait a second so user can see the program work
Sleep(1000);
}