108 lines
3.9 KiB
C#
108 lines
3.9 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|