最近需要用到按键模拟,早就听说过WinIo大名,这次试用了一下,写下使用笔记。
WinIo可以到官方网站:http://www.internals.com/去下载,里面包含了帮助文档和源码。
因为需要加载驱动,程序要以管理员权限运行,我用的是64位WIN7系统,还需要对WinIo64.sys做交叉签名才能正常加载,没有签名的同学需要使用32位系统或使用测试模式。
看网上的资料一般都是先调用InstallWinIoDriver
可以看到,它会自动识别32位还是64位系统,自己去加载驱动,只要把驱动放到exe同目录下就可以了。
其它的就简单了,贴一下代码,代码前半部分网上COPY :)
最后附上WINIO3.0的驱动和源码:WinIo3.0
WinIo可以到官方网站:http://www.internals.com/去下载,里面包含了帮助文档和源码。
因为需要加载驱动,程序要以管理员权限运行,我用的是64位WIN7系统,还需要对WinIo64.sys做交叉签名才能正常加载,没有签名的同学需要使用32位系统或使用测试模式。
为了省去动态加载DLL,再动态获取函数地址去调用的麻烦,用官方的DLL源码,编译生成WinIo.lib,添加一行#pragmacomment(lib,"WinIo.lib"),修改一下winio.h,然后include就可以了。
看网上的资料一般都是先调用InstallWinIoDriver
IsDemandLoaded必须要设为false,但是我想以SERVICE_DEMAND_START方式启动,就自行改为true了,后来发现其实没必要调用这个函数,直接调用InitializeWinIo就可以了。下面是InitializeWinIo的源码:
bool GetDriverPath() { PWSTR pszSlash; if (!GetModuleFileName(GetModuleHandle(NULL), szWinIoDriverPath, sizeof(szWinIoDriverPath))) return false; pszSlash = wcsrchr(szWinIoDriverPath, '\\'); if (pszSlash) pszSlash[1] = 0; else return false; if (g_Is64BitOS) wcscat(szWinIoDriverPath, L"winio64.sys"); else wcscat(szWinIoDriverPath, L"winio32.sys"); return true; } bool __stdcall InitializeWinIo() { bool bResult; DWORD dwBytesReturned; g_Is64BitOS = Is64BitOS(); hDriver = CreateFile(L"\\\\.\\WINIO", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // If the driver is not running, install it if (hDriver == INVALID_HANDLE_VALUE) { GetDriverPath(); bResult = InstallWinIoDriver(szWinIoDriverPath, true); if (!bResult) return false; bResult = StartWinIoDriver(); if (!bResult) return false; hDriver = CreateFile(L"\\\\.\\WINIO", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDriver == INVALID_HANDLE_VALUE) return false; } // Enable I/O port access for this process if running on a 32 bit OS if (!g_Is64BitOS) { if (!DeviceIoControl(hDriver, IOCTL_WINIO_ENABLEDIRECTIO, NULL, 0, NULL, 0, &dwBytesReturned, NULL)) { return false; } } IsWinIoInitialized = true; return true; }
可以看到,它会自动识别32位还是64位系统,自己去加载驱动,只要把驱动放到exe同目录下就可以了。
其它的就简单了,贴一下代码,代码前半部分网上COPY :)
#include "stdafx.h" #include "winio.h" #pragma comment(lib,"WinIo.lib") #define KBC_CMD 0x64 #define KBC_DATA 0x60 void KBCWait4IBE() { DWORD dwVal=0; do { GetPortVal(KBC_CMD,&dwVal,1); }while((&dwVal)&&(0x2)==0); } void MyKeyDown(DWORD KCode) { Sleep(20); //休息2秒 KBCWait4IBE(); //等待键盘缓冲区为空 SetPortVal( 0X64, 0xD2, 1 ); //发送键盘写入命令 Sleep(10); KBCWait4IBE(); SetPortVal( 0X60, MapVirtualKey(KCode, 0), 1 ); //写入按键信息,按下键 } void MyKeyUp(DWORD KCode) { Sleep(10); KBCWait4IBE(); //等待键盘缓冲区为空 if (SetPortVal(0X64, 0xD2, 1 )) //发送键盘写入命令 Sleep(10); KBCWait4IBE(); SetPortVal(0X60, (MapVirtualKey(KCode, 0) | 0x80), 1);//写入按键信息,释放键 } int _tmain(int argc, _TCHAR* argv[]) { bool bRet = false; bRet = InitializeWinIo(); if (bRet) { Sleep(2000); MyKeyDown(66); MyKeyUp(66); } RemoveWinIoDriver(); return 0; }
最后附上WINIO3.0的驱动和源码:WinIo3.0
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10853847
每日一句
Challenges spark life; conquering them gives purpose.
挑战点亮生活,征服赋予意义。
挑战点亮生活,征服赋予意义。
新会员