C# PuppeteerSharp项目如何全局监听左右方向键按下并执行对应逻辑
解决方案
实现思路
因为你的需求是程序未聚焦时也能检测全局按键,普通控制台按键监听接口仅能响应程序聚焦时的输入,因此必须调用Windows底层的低级别键盘钩子(Low Level Keyboard Hook)API实现全局监听,PuppeteerSharp本身不提供跨窗口的全局按键检测能力。
完整实现代码
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; using PuppeteerSharp; namespace GoogleMapsChecker { internal class Program { // 键盘钩子相关常量定义 private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private const int VK_LEFT = 0x25; private const int VK_RIGHT = 0x27; private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; // 业务逻辑标记,避免按键重复触发,不需要连续触发可保留 private static bool _isProcessing = false; private static async Task Main(string[] args) { // 注册全局键盘钩子 _hookID = SetHook(_proc); try { // 原有PuppeteerSharp逻辑 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false, ExecutablePath = @"C:\Program Files\Google\Chrome\Application\chrome.exe" }); var page = await browser.NewPageAsync(); var searchTerm = "searchTerm"; await page.GoToAsync("https://www.google.ch/"); await Task.Delay(5000); await page.ClickAsync(".gLFyf"); await page.Keyboard.SendCharacterAsync(searchTerm); await page.Keyboard.PressAsync("Enter"); Console.WriteLine("已就绪,按左/右方向键执行对应操作,按Q退出程序"); // 保持程序运行不退出 while (true) { var key = Console.ReadKey(true); if (key.Key == ConsoleKey.Q) { break; } await Task.Delay(100); } } finally { // 退出时卸载钩子,避免资源泄漏 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 delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); // 钩子回调函数 private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && !_isProcessing) { int vkCode = Marshal.ReadInt32(lParam); switch (vkCode) { case VK_LEFT: _isProcessing = true; // 左方向键业务逻辑 Console.WriteLine("检测到左方向键按下"); _ = Task.Run(async () => { try { // 此处替换为你的左按键业务逻辑 await Task.CompletedTask; } finally { _isProcessing = false; } }); break; case VK_RIGHT: _isProcessing = true; // 右方向键业务逻辑 Console.WriteLine("检测到右方向键按下"); _ = Task.Run(async () => { try { // 此处替换为你的右按键业务逻辑 await Task.CompletedTask; } finally { _isProcessing = false; } }); break; } } // 其他按键直接透传,不影响系统正常输入 return CallNextHookEx(_hookID, nCode, wParam, lParam); } // 导入Win32 API [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); } }
注意事项
- 该实现仅支持Windows系统,低级别键盘钩子是Windows平台专属API
- 不需要限制单次按键触发的话可以删除
_isProcessing相关逻辑 - 所有非左右方向键的输入都会正常透传给系统,不会影响其他软件的正常使用
内容的提问来源于stack exchange,提问作者Nightscape
相关产品推荐
相关产品推荐

