我的问题是关于非常古老的技术。我的任务是自动化在 Windows 98 中以 Windows 模式运行的旧 DOS 软件(光谱)。我做了两个不同的解决方案,但它们都不适用于 DOS 应用程序:
第一个解决方案
- 激活 DOS 应用程序
- 通过 SendInput 函数发送输入,如下所示:
void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaInput(const std::vector<DWORD>& keys, int keyPause)
{
std::vector<DWORD>::const_iterator it;
INPUT keyBoardInput;
keyBoardInput.type = INPUT_KEYBOARD;
keyBoardInput.ki.wScan = 0;
keyBoardInput.ki.time = 0;
keyBoardInput.ki.dwExtraInfo = 0;
for(it = keys.begin(); it != keys.end(); it++)
{
keyBoardInput.ki.wVk = (*it);
keyBoardInput.ki.dwFlags = 0; // key down
SendInput(1, &keyBoardInput, sizeof(INPUT));
Sleep(keyPause);
keyBoardInput.ki.dwFlags = 2; // key up
SendInput(1, &keyBoardInput, sizeof(INPUT));
Sleep(keyPause);
}
}
- 通过 i8042 键盘控制器生成按键:使用 D2 命令写入键盘缓冲区命令,如下所示(KEYBOARD_CMD_REG - 0x64,KEYBOARD_DATA_REG - 0x60):
void MossbauerLab::Sm2201::SaveManager::AutoSaveManager::sendKeysViaKeyboardController(const std::vector<BYTE>& scanCodes, int keyPause)
{
std::vector<BYTE>::const_iterator it;
for(it = scanCodes.begin(); it != scanCodes.end(); it++)
{
// wait untill buffer is empty
int status = 0;
int result = 0;
do
{
status = _inp(0x64);
// std::cout <<"Keyboard status: "<< status << std::endl;
Sleep(10);
}
while (status & 1);
// send scan code for key down
_outp(KEYBOARD_CMD_REG, 0xD2);
_outp(KEYBOARD_DATA_REG, (*it));
result = _inp(KEYBOARD_DATA_REG);
std::cout <<"Keyboard command result for KEY DOWN: "<< result << std::endl;
// send scan code for key up
BYTE keyUpCode = (*it) | 128;
Sleep(keyPause);
_outp(KEYBOARD_CMD_REG, 0xD2);
_outp(KEYBOARD_DATA_REG, keyUpCode);
result = _inp(KEYBOARD_DATA_REG);
std::cout <<"Keyboard command result for KEY UP: "<< result << std::endl;
}
}
我用标准记事本窗口(notepad.exe)测试了这两种解决方案,它们都工作正常,但我无法让它与 DOS 应用程序一起工作。
我在其中生成键盘输入(和整个项目)的代码:https ://github.com/MossbauerLab/Sm2201Autosave/blob/master/MossbauerLab.Sm2201.ExtSaveUtility/src/saveManager/autoSaveManager.cpp
你能帮我解决这个问题吗?