Reputation: 21
Statistical program. Not a keyllogger. For me, to know how much of my life I waste by tapping without meaning into the keyboard;}}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StatisticChar
{
public partial class Form1 : Form
{
private GlobalKeyboardHook _globalKeyboardHook;
public void SetupKeyboardHooks()
{
_globalKeyboardHook = new GlobalKeyboardHook();
_globalKeyboardHook.KeyboardPressed += OnKeyPressed;
}
private void OnKeyPressed(object sender, GlobalKeyboardHookEventArgs e)
{
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown)
{
var znak = $"{(char)e.KeyboardData.VirtualCode} {e.KeyboardData.VirtualCode}";
////////////////////// SEKCJA F1 ///////////////////////////////////////////
if ((e.KeyboardData.VirtualCode >= 112) && (e.KeyboardData.VirtualCode <= 123))
{
znak = "F" + (e.KeyboardData.VirtualCode - 111).ToString();
}
////////////////////// SEKCJA NUMERYCZNA ///////////////////////////////////////////
if ((e.KeyboardData.VirtualCode >= 96) && (e.KeyboardData.VirtualCode <= 105))
{
znak = (e.KeyboardData.VirtualCode - 96).ToString();
}
if (e.KeyboardData.VirtualCode == 144)
{
znak = "NumLock";
}
if (e.KeyboardData.VirtualCode == 111)
{
znak = "/";
}
if (e.KeyboardData.VirtualCode == 106)
{
znak = "*";
}
if (e.KeyboardData.VirtualCode == 109)
{
znak = "-";
}
if (e.KeyboardData.VirtualCode == 107)
{
znak = "+";
}
if (e.KeyboardData.VirtualCode == 107)
{
znak = ",";
}
////////////////////// SEKCJA GŁÓWNA ///////////////////////////////////////////
if (e.KeyboardData.VirtualCode == 13)
{
znak = "ENTER";
}
if (e.KeyboardData.VirtualCode == 192)
{
znak = "`";
}
if (e.KeyboardData.VirtualCode == 9)
{
znak = "tabulator";
}
if (e.KeyboardData.VirtualCode == 20)
{
znak = "capslock";
}
if (e.KeyboardData.VirtualCode == 160)
{
znak = "LewyShift";
}
if (e.KeyboardData.VirtualCode == 162)
{
znak = "ctrl";
}
if (e.KeyboardData.VirtualCode == 91)
{
znak = "win";
}
if (e.KeyboardData.VirtualCode == 32)
{
znak = "spacja";
}
if (e.KeyboardData.VirtualCode == 37)
{
znak = "←";
}
if (e.KeyboardData.VirtualCode == 39)
{
znak = "→";
}
if (e.KeyboardData.VirtualCode == 38)
{
znak = "↑";
}
if (e.KeyboardData.VirtualCode == 40)
{
znak = "↓";
}
if (e.KeyboardData.VirtualCode == 8)
{
znak = "backup";
}
if (e.KeyboardData.VirtualCode == 161)
{
znak = "prawyShift";
}
if (e.KeyboardData.VirtualCode == 93)
{
znak = "ppm";
}
if (e.KeyboardData.VirtualCode == 45)
{
znak = "insert";
}
if (e.KeyboardData.VirtualCode == 44)
{
znak = "printscreen";
}
if (e.KeyboardData.VirtualCode == 19)
{
znak = "pause";
}
if (e.KeyboardData.VirtualCode == 166)
{
znak = "back";
}
if (e.KeyboardData.VirtualCode == 36)
{
znak = "home";
}
if (e.KeyboardData.VirtualCode == 35)
{
znak = "end";
}
if (e.KeyboardData.VirtualCode == 46)
{
znak = "delete";
}
if (e.KeyboardData.VirtualCode == 33)
{
znak = "pageUp";
}
if (e.KeyboardData.VirtualCode == 34)
{
znak = "pagDown";
}
if (e.KeyboardData.VirtualCode == 163)
{
znak = "PrawyCtrl";
}
////////////////////// INNE, POZOSTAŁE ///////////////////////////////////////////
if (e.KeyboardData.VirtualCode == 1)
{
znak = "LeftClick";
}
if (e.KeyboardData.VirtualCode == 2)
{
znak = "RightClick";
}
Statystyki[znak] = Statystyki.ContainsKey(znak) ? ++Statystyki[znak] : 1;
}
}
public new void Dispose()
{
base.Dispose();
_globalKeyboardHook?.Dispose();
}
private DateTime data_zbierania_statystyk;
private static readonly Dictionary<string, int> Statystyki = new Dictionary<string, int>();
public Form1()
{
_globalKeyboardHook = new GlobalKeyboardHook();
SetupKeyboardHooks();
var dt = DateTime.Now;
data_zbierania_statystyk = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
Timer timer = new Timer
{
Interval = 1 * 10 * 1000
};
timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
Timer timer2 = new Timer
{
Interval = 1000
};
timer2.Tick += new EventHandler(Timer2_Tick);
timer2.Start();
InitializeComponent();
}
private void Timer2_Tick(object sender, EventArgs e)
{
richTextBox1.Text = StatystykiJakoText();
}
void Timer_Tick(object sender, EventArgs e)
{
Saves();
}
void Saves()
{
var dt = DateTime.Now;
var now = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
if (data_zbierania_statystyk < now)
{
data_zbierania_statystyk = now;
string sb = StatystykiJakoText();
string path = $@"O:\statystyki{dt.Year}-{dt.Month}-{dt.Day}.txt";
File.AppendAllText(path, sb);
richTextBox1.Text = "";
richTextBox1.Text = sb.ToString();
}
}
private string StatystykiJakoText()
{
var sb = new StringBuilder();
sb.Append(Environment.NewLine);
sb.Append($"Statystyki za dzień: {data_zbierania_statystyk}{Environment.NewLine}");
foreach (var literka in Statystyki)
{
sb.Append($"{literka.Key} - {literka.Value}{Environment.NewLine}");
}
return sb.ToString();
}
}
}
However, there is still a problem:
Does not catch characters written in some programs, eg Notepad ++? Is anyone able to say why this is happening and how to fix it?
How to handle shortcuts eg ctrl + c, ctrl + v?
Upvotes: 2
Views: 310
Reputation: 17007
If you want a full keyboard hook, it will be more interesting to use these functions:
public class WindowsHookAPI
{
//public delegate IntPtr HookDelegate(
// Int32 Code, IntPtr wParam, IntPtr lParam);
public delegate IntPtr HookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
public static extern IntPtr CallNextHookEx(IntPtr hHook, Int32 nCode, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
public static extern IntPtr UnhookWindowsHookEx(IntPtr hHook);
[DllImport("User32.dll")]
public static extern IntPtr SetWindowsHookEx(Int32 idHook, HookDelegate lpfn, IntPtr hmod, Int32 dwThreadId);
}
you are sure to trap all keys and you could easily block some keys if you want..
"its the origin of hook"
you install the global hook like this:
keyBoardHandle = WindowsHookAPI.SetWindowsHookEx(WH_KEYBOARD_LL, keyBoardDelegate, IntPtr.Zero, 0);
and a sample to use it:
private WindowsHookAPI.HookDelegate keyBoardDelegate;
private IntPtr keyBoardHandle;
// Hook global keyboard
private const Int32 WH_KEYBOARD_LL = 13;
// flags bits of lParam hookstruct
private const Int32 LLKHF_EXTENDED = 0b00000001;
private const Int32 LLKHF_LOWER_IL_INJECTED = 0b00000010;
private const Int32 LLKHF_INJECTED = 0b00010000;
private const Int32 LLKHF_ALTDOWN = 0b00100000;
private const Int32 LLKHF_UP = 0b10000000;
// value of wParam
private const Int32 WM_KEYUP = 0x0101;
private const Int32 WM_KEYDOWN = 0x0100;
private IntPtr KeyboardHookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam)
{
hookStruct param = (hookStruct)Marshal.PtrToStructure(lParam, typeof(hookStruct));
if (Code < 0 || (param.flags & LLKHF_INJECTED) != 0)
{
return WindowsHookAPI.CallNextHookEx(keyBoardHandle, Code, wParam, lParam);
}
if ((int)wParam == WM_KEYDOWN)
{
// see https://learn.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagkbdllhookstruct
// for more explanations about type of keys trapped
// return (IntPtr)1; // if you want to block some keys
}
return WindowsHookAPI.CallNextHookEx(keyBoardHandle, Code, wParam, lParam);
}
public struct hookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
to unhook use:
WindowsHookAPI.UnhookWindowsHookEx(keyBoardHandle);
Upvotes: 2