using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Win32; static class Program { const int WH_KEYBOARD_LL = 13; const int VK_CAPITAL = 0x14; delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr GetModuleHandle(string lpModuleName); [StructLayout(LayoutKind.Sequential)] struct KBDLLHOOKSTRUCT { public uint vkCode; public uint scanCode; public uint flags; public uint time; public IntPtr dwExtraInfo; } static LowLevelKeyboardProc _proc = HookCallback; static IntPtr _hookId = IntPtr.Zero; static NotifyIcon? _trayIcon; [STAThread] static void Main() { RegisterStartup(); using var mutex = new Mutex(true, @"Global\FuckCapsLock", out var createdNew); if (!createdNew) return; _hookId = SetHook(_proc); if (_hookId == IntPtr.Zero) return; ApplicationConfiguration.Initialize(); using var form = new Form(); form.WindowState = FormWindowState.Minimized; form.ShowInTaskbar = false; form.Load += (_, _) => form.Hide(); _trayIcon = new NotifyIcon { Icon = SystemIcons.Application, Text = "FuckCapsLock", ContextMenuStrip = new ContextMenuStrip() }; _trayIcon.ContextMenuStrip.Items.Add("Exit", null, (_, _) => { _trayIcon.Visible = false; Application.Exit(); }); _trayIcon.Visible = true; Application.Run(form); UnhookWindowsHookEx(_hookId); } static void RegisterStartup() { try { using var key = Registry.CurrentUser.OpenSubKey( @"Software\Microsoft\Windows\CurrentVersion\Run", true); if (key is null) return; var path = Environment.ProcessPath; if (path is null) return; var value = path.Contains(' ') ? $"\"{path}\"" : path; var existing = key.GetValue("FuckCapsLock") as string; if (!string.Equals(existing, value, StringComparison.OrdinalIgnoreCase)) key.SetValue("FuckCapsLock", value); } catch { } } static IntPtr SetHook(LowLevelKeyboardProc proc) { using var curProcess = Process.GetCurrentProcess(); using var curModule = curProcess.MainModule; return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule!.ModuleName), 0); } static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) { var hookStruct = Marshal.PtrToStructure(lParam); if (hookStruct.vkCode == VK_CAPITAL) return (IntPtr)1; } return CallNextHookEx(_hookId, nCode, wParam, lParam); } }