【发布时间】:2020-05-14 17:02:29
【问题描述】:
我的问题是关于非常古老的技术。我的任务是自动化在 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
你能帮我解决这个问题吗?
【问题讨论】:
-
您尝试执行的操作不起作用,因为 MS-DOS 应用程序运行在与运行 Windows 的主 VM 不同的 VM 中。这两个 VM 有两个不同的虚拟化键盘控制器。缺少编写 VxD(32 位驱动程序)我不确定有没有办法做你想做的事。
-
也许有办法以某种方式写入 MS-DOS Vx 键盘驱动程序?
-
Ross,感谢您对我以前从未听说过的有关 VxD 的评论,我搜索了有关虚拟键盘驱动程序并找到了有趣的链接:www-user.tu-chemnitz.de/~heha/vxd/vxd.htm#C09S02 可能它可以帮助我找到解决方案
-
这正是您所需要的。您必须自己编写才能编写自己的 VxD,例如您链接的“VSAMPLED”示例,但它不是键盘驱动程序。相反,它将只使用 Windows 虚拟键盘驱动程序 (VKD) 公开的 API,例如示例代码如何使用 VKD_Force_Keys。
标签: c++ dos keyboard-input windows-98