using System; using System.Runtime.InteropServices; using System.Text; using System.Threading; namespace GlobalKeyboardHook { class Program { // Define the hook type const int WH_KEYBOARD_LL = 13; const int WM_KEYDOWN = 0x0100; const int WM_KEYUP = 0x0101; // Define the key codes const int VK_RETURN = 0x0D; // Enter key // Declare the hook handle and the hook procedure private static IntPtr hookId = IntPtr.Zero; private static StringBuilder scannedData = new StringBuilder(); // Define the delegate for the hook procedure private static LowLevelKeyboardProc _proc = HookCallback; // P/Invoke to set the hook [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowsHookEx(int hookType, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId); [DllImport("user32.dll")] public static extern bool UnhookWindowsHookEx(IntPtr hookId); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr CallNextHookEx(IntPtr hookId, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string lpModuleName); // The delegate type for the hook procedure public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); static void Main(string[] args) { // Hook the keyboard input globally hookId = SetHook(_proc); // Wait for the user to terminate the application Console.WriteLine("请扫描条形码..."); Console.WriteLine("按 ESC 键退出程序。"); // Loop indefinitely until the user presses the ESC key while (true) { if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape) { break; // Exit the loop and terminate the application } Thread.Sleep(10); // Sleep to avoid high CPU usage } // Unhook the keyboard input when done UnhookWindowsHookEx(hookId); } // Set the hook for keyboard input private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (var curProcess = System.Diagnostics.Process.GetCurrentProcess()) using (var curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } // The callback function that will be called when a key is pressed or released private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && (int)wParam == WM_KEYDOWN) { // Get the key code int vkCode = Marshal.ReadInt32(lParam); // If the key is Enter (Carriage Return), treat it as the end of the barcode if (vkCode == VK_RETURN) { // Print the scanned data string data = scannedData.ToString(); Console.WriteLine($"\n条码扫描完成,扫描到的数据是: {data}"); // Clear the scanned data for the next scan scannedData.Clear(); } else { // Append the character corresponding to the key code char keyChar = (char)vkCode; scannedData.Append(keyChar); // Print the character in real-time (optional) Console.Write(keyChar); } } // Call the next hook in the chain return CallNextHookEx(hookId, nCode, wParam, lParam); } } }