后台记录键盘输入

该代码示例展示了如何利用WindowsAPI创建一个低级键盘钩子,以捕获并记录键盘的按下和弹起事件。程序会记录按键名称、时间戳以及按键持续时间,并将数据写入文本文件。它可以与JavaRobot类结合,用于模拟键盘输入。
摘要由CSDN通过智能技术生成

自动记录键盘每个按键的按下弹起的信息,JPX.txt的内容可以配合我前面文章JavaRobot模拟键盘输入

参考了ka2x的作品:写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor?spm=1001.2014.3001.5352

当控制台出现程序就绪就已经开始了

关闭:直接把控制台关闭了就可以了

#define _CRT_SECURE_NO_WARNINGS //VS中必须定义,否则报错
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <ctime>
#include <fstream>

using namespace std;

char KeyWord[256][20] = {
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Backspace"},
	{"Tab"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Enter"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Pause"},
	{"CapsLock"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Esc"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Space"},
	{"PgUp"},
	{"PgDn"},
	{"End"},
	{"Home"},
	{"←"},
	{"↑"},
	{"→"},
	{"↓"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"PrScr"},
	{"Ins"},
	{"Del"},
	{"undefined"},
	{"0"},
	{"1"},
	{"2"},
	{"3"},
	{"4"},
	{"5"},
	{"6"},
	{"7"},
	{"8"},
	{"9"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"A"},
	{"B"},
	{"C"},
	{"D"},
	{"E"},
	{"F"},
	{"G"},
	{"H"},
	{"I"},
	{"J"},
	{"K"},
	{"L"},
	{"M"},
	{"N"},
	{"O"},
	{"P"},
	{"Q"},
	{"R"},
	{"S"},
	{"T"},
	{"U"},
	{"V"},
	{"W"},
	{"X"},
	{"Y"},
	{"Z"},
	{"Win"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"0"},
	{"1"},
	{"2"},
	{"3"},
	{"4"},
	{"5"},
	{"6"},
	{"7"},
	{"8"},
	{"9"},
	{"*"},
	{"+"},
	{"undefined"},
	{"-"},
	{"."},
	{"/"},
	{"F1"},
	{"F2"},
	{"F3"},
	{"F4"},
	{"F5"},
	{"F6"},
	{"F7"},
	{"F8"},
	{"F9"},
	{"F10"},
	{"F11"},
	{"F12"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"NumLock"},
	{"ScrLk"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"Shift"},
	{"Shift"},
	{"L-Ctrl"},
	{"R-Ctrl"},
	{"L-Alt"},
	{"R-Alt"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{";"},
	{"="},
	{","},
	{"-"},
	{"."},
	{"/"},
	{"`"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"["},
	{"\\"},
	{"]"},
	{"'"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{"undefined"},
	{ "undefined" } };
	char JPXKeyWord[256][20] = {
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Backspace"},
	{"Tab"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Enter"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Pause"},
	{"Cap"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Esc"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Space"},
	{"PgUp"},
	{"PgDn"},
	{"End"},
	{"Home"},
	{"Right"},
	{"Up"},
	{"Letf"},
	{"Down"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Ins"},
	{"Del"},
	{"-1"},
	{"0"},
	{"1"},
	{"2"},
	{"3"},
	{"4"},
	{"5"},
	{"6"},
	{"7"},
	{"8"},
	{"9"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"a"},
	{"b"},
	{"c"},
	{"d"},
	{"e"},
	{"f"},
	{"g"},
	{"h"},
	{"i"},
	{"j"},
	{"k"},
	{"l"},
	{"m"},
	{"n"},
	{"o"},
	{"p"},
	{"q"},
	{"r"},
	{"s"},
	{"t"},
	{"u"},
	{"v"},
	{"w"},
	{"x"},
	{"y"},
	{"z"},
	{"Win"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"0"},
	{"1"},
	{"2"},
	{"3"},
	{"4"},
	{"5"},
	{"6"},
	{"7"},
	{"8"},
	{"9"},
	{"*"},
	{"+"},
	{"-1"},
	{"-"},
	{"."},
	{"/"},
	{"F1"},
	{"F2"},
	{"F3"},
	{"F4"},
	{"F5"},
	{"F6"},
	{"F7"},
	{"F8"},
	{"F9"},
	{"F10"},
	{"F11"},
	{"F12"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"Shift"},
	{"Shift"},
	{"Ctrl"},
	{"Ctrl"},
	{"Alt"},
	{"Alt"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{";"},
	{"="},
	{","},
	{"-"},
	{"."},
	{"/"},
	{"`"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"["},
	{"-1"},
	{"]"},
	{"'"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{"-1"},
	{ "-1" } };
int ft = 0, et = 0;

tm TimeN() {//获取时间
	time_t nowtime;
	time(&nowtime); //获取1900年1月1日0点0分0秒到现在经过的秒数
	tm p;
	localtime_s(&p, &nowtime); //将秒数转换为本地时间,年从1900算起,需要+1900,月为0-11,所以要+1
	return p;
}

void RC(string ss);

void Remove(string name) {
	try
	{
		fstream fout(name, ios::out | ios::trunc);
		fout << "";
		fout.close();

	}
	catch (exception& e)
	{
		RC("error happened : Remove(string name);");
	}
}

void RC(string ss) {
	ofstream location_out;
	location_out.open("Wrong.txt", std::ios::out | std::ios::app);  //以写入和在文件末尾添加的方式打开.txt文件,没有的话就创建该文件。
	if (!location_out.is_open())
		return ;
	tm p = TimeN();
	location_out << p.tm_year + 1900 << "-" << p.tm_mon + 1 << "-" << p.tm_mday << " " << p.tm_hour << ":" << p.tm_min << ":" << p.tm_sec << "  " << ss << endl;

	location_out.close();
}

void RC1(tm p, KBDLLHOOKSTRUCT* ks,int time ,int num) {
	ofstream location_out;
	location_out.open("Data.txt", std::ios::out | std::ios::app);  //以写入和在文件末尾添加的方式打开.txt文件,没有的话就创建该文件。
	if (!location_out.is_open())//判断是否打开了
		return ;
	if (time == 0 && num == 0) {
		location_out << p.tm_year + 1900 << "-" << p.tm_mon + 1 << "-" << p.tm_mday << " " << p.tm_hour << ":" << p.tm_min << ":" << p.tm_sec << "  +" << KeyWord[ks->vkCode] << "\n";
	}
	else if (time != 0 && num != 0) {
		location_out << p.tm_year + 1900 << "-" << p.tm_mon + 1 << "-" << p.tm_mday << " " << p.tm_hour << ":" << p.tm_min << ":" << p.tm_sec << "  -" << KeyWord[ks->vkCode] << "  " << time << "ms  (" << num << ")" << "\n";
	}
	else {
		location_out << p.tm_year + 1900 << "-" << p.tm_mon + 1 << "-" << p.tm_mday << " " << p.tm_hour << ":" << p.tm_min << ":" << p.tm_sec << "  -" << KeyWord[ks->vkCode] << "  " << time << "ms   " << "\n";
	}

	location_out.close();//关闭
}

bool str_same(char* p1, char* p2)//比较字符串
{
	if (strcmp(p1, p2))
		return 0;
	else
		for (int i = 0; i < strlen(p1) + 1; i++)
		{
			if (p1[i] != p2[i])
				return 0;
		}
	return 1;
}

int chick(char* a) {//排除非功能键
	char b[4][4] = { {"F10"},{"F11"}, {"F12"},{"Up"} };
	int i;
	char* c;
	for (i = 0, c = a; *c; ++i, ++c);
	if (str_same(a, b[3])) {
		return 2;
	}
	else if (i <= 2 || str_same(a, b[0]) || str_same(a, b[1]) || str_same(a, b[2])) {
		return 1;
	}
	return 2;
}

void RC2(KBDLLHOOKSTRUCT* ks,int num) {
	ofstream location_out;
	location_out.open("JPX.txt", std::ios::out | std::ios::app);  //以写入和在文件末尾添加的方式打开.txt文件,没有的话就创建该文件。
	if (!location_out.is_open())//判断是否打开了
		return;
	if (num == 0) {//为按下
		if (chick(JPXKeyWord[ks->vkCode]) == 2) {//为功能
			location_out << "+" << JPXKeyWord[ks->vkCode] << " ";
		}
		else {
			location_out << JPXKeyWord[ks->vkCode] << " ";
		}
	}
	else {
		if (chick(JPXKeyWord[ks->vkCode]) == 2) {//为功能
			location_out << "-" << JPXKeyWord[ks->vkCode] << " ";
		}
		else if(num != 1){
			for (int i = 1; i < num; i++) {
				location_out << JPXKeyWord[ks->vkCode] << " ";
			}
		}
	}

	location_out.close();//关闭
}

char *lok1 = KeyWord[0];//初始化记录数组
int num = 1;//初始化次数

HHOOK keyboardHook = 0;		// 钩子句柄、

LRESULT CALLBACK LowLevelKeyboardProc(
	_In_ int nCode,		// 规定钩子如何处理消息,小于 0 则直接 CallNextHookEx
	_In_ WPARAM wParam,	// 消息类型
	_In_ LPARAM lParam	// 指向某个结构体的指针,这里是 KBDLLHOOKSTRUCT(低级键盘输入事件)
) {
	KBDLLHOOKSTRUCT* ks = (KBDLLHOOKSTRUCT*)lParam;
	tm p = TimeN();//获取时间
	if (ks->flags == 0 || ks->flags == 1) {
		if (lok1 == KeyWord[ks->vkCode]) {//判断是不是长按
			num++;//次数增加
		}
		else {
			lok1 = KeyWord[ks->vkCode];//获取当前按键名
			ft = ks->time;//获取按下时刻
			printf("%04d-%02d-%02d %02d:%02d:%02d  +%-10s \n", p.tm_year + 1900, p.tm_mon + 1, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec, KeyWord[ks->vkCode]);
			RC1(p, ks, 0, 0);
			RC2(ks, 0);
		}
	}else if (ks->flags == 128 || ks->flags == 129) {
		lok1 = KeyWord[0];//初始化
		et = ks->time;//获取弹起时刻
		if (num != 1) {//判断是否长按
			printf("%04d-%02d-%02d %02d:%02d:%02d  -%-10s %5dms (%d)\n", p.tm_year + 1900, p.tm_mon + 1, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec, KeyWord[ks->vkCode], et - ft, num);
			RC1(p, ks, et - ft, num);
			RC2(ks, num);
			num = 1;//初始化
		}
		else {
			printf("%04d-%02d-%02d %02d:%02d:%02d  -%-10s %5dms\n", p.tm_year + 1900, p.tm_mon + 1, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec, KeyWord[ks->vkCode], et - ft);
			RC1(p, ks, et - ft, 0);
			RC2(ks, 1);
		}
	}
	else {//判断ks->flags是否超出预料
		RC("LRESULT CALLBACK LowLevelKeyboardProc : wrong(ks->flags)\n");
	}
	// 将消息传递给钩子链中的下一个钩子
	return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main()
{
	ofstream location_out;
	location_out.open("Data.txt", std::ios::out | std::ios::app);  //以写入和在文件末尾添加的方式打开.txt文件,没有的话就创建该文件。
	location_out.close();
	location_out.open("Wrong.txt", std::ios::out | std::ios::app);
	location_out.close();
	location_out.open("JPX.txt", std::ios::out | std::ios::app);
	location_out.close();
	Remove("Wrong.txt");//清空文件
	Remove("Data.txt");
	Remove("JPX.txt");
	// 安装钩子
	keyboardHook = SetWindowsHookEx(
		WH_KEYBOARD_LL,			// 钩子类型,WH_KEYBOARD_LL 为键盘钩子
		LowLevelKeyboardProc,	// 指向钩子函数的指针
		GetModuleHandleA(NULL),	// Dll 句柄
		NULL
	);
	if (keyboardHook == 0) { RC("main() : 挂钩键盘失败\n"); return -1; }
	MSG msg;
	printf("===程序就绪===\n");
	while (1)
	{
		// 如果消息队列中有消息
		if (PeekMessageA(
			&msg,		// MSG 接收这个消息
			NULL,		// 检测消息的窗口句柄,NULL:检索当前线程所有窗口消息
			NULL,		// 检查消息范围中第一个消息的值,NULL:检查所有消息(必须和下面的同时为NULL)
			NULL,		// 检查消息范围中最后一个消息的值,NULL:检查所有消息(必须和上面的同时为NULL)
			PM_REMOVE	// 处理消息的方式,PM_REMOVE:处理后将消息从队列中删除
		)) {
			TranslateMessage(&msg);
			DispatchMessageW(&msg);
		}
		else
			Sleep(0);    //避免占用资源过高
	}
	UnhookWindowsHookEx(keyboardHook);// 删除钩子
	return 0;
}

控制台内容

产生文件

如何与JavaRobot模拟键盘输入程序配合

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y海森伯格Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值