如何在C#中实现游戏自动按键宏,支持指定窗口触发和手动中断?
实现方案
核心逻辑说明
- 按键模拟:调用Windows原生API
PostMessage向目标窗口发送按键按下(WM_KEYDOWN)、按键释放(WM_KEYUP)消息,可自由组合实现按下不释放、单击两种操作 - 窗口限定:通过
GetForegroundWindow获取当前活动窗口句柄,每次发送按键前校验当前活动窗口是否为启动时记录的目标窗口,不匹配则不发送按键 - 中止逻辑:通过
GetAsyncKeyStateAPI实时检测中止键状态,只要检测到按键被按下就立刻跳出执行循环
完整修改后代码
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace BedWarsDropBot { public class Program { // Win32 API 声明 [DllImport("user32.dll")] private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); // 按键消息常量 private const uint WM_KEYDOWN = 0x0100; private const uint WM_KEYUP = 0x0101; public static void Main(string[] args) { Console.WriteLine("BedWars Drop Bot.\n\n"); Console.WriteLine("This is a bot for dropping items on Bedwars. To start dropping, press V. To stop dropping, press X. To close, press Z.\n"); var option = Console.ReadKey(); bool isRunning = true; switch (option.Key) { case ConsoleKey.V: Console.WriteLine("\nPlease enter your drop key/the key you would like to be pressed:\n"); var pressKey = Console.ReadKey(); Console.WriteLine("\nThe program is giving you 5 seconds to open up Bedwars, so that the program can start doing what it is meant to."); Thread.Sleep(5000); // 记录5秒后当前的活动窗口作为目标窗口 IntPtr targetWindow = GetForegroundWindow(); Console.WriteLine("已绑定目标窗口,自动按键开始,按X可终止"); while (isRunning) { // 检测是否按下中止键X if (GetAsyncKeyState((int)ConsoleKey.X) != 0) { isRunning = false; Console.WriteLine("已终止自动按键流程"); break; } // 校验当前活动窗口是否为目标窗口 if (GetForegroundWindow() != targetWindow) { Thread.Sleep(10); continue; } // 单击按键实现:按下+释放 PostMessage(targetWindow, WM_KEYDOWN, (IntPtr)pressKey.Key, IntPtr.Zero); Thread.Sleep(10); PostMessage(targetWindow, WM_KEYUP, (IntPtr)pressKey.Key, IntPtr.Zero); // 两次按键的间隔,可根据需求调整 Thread.Sleep(100); // 若需要实现按下不释放的操作,仅保留WM_KEYDOWN逻辑,需要释放时再发送WM_KEYUP即可 } break; case ConsoleKey.X: break; case ConsoleKey.Z: Console.WriteLine("\nYou chose to close this program. Are you sure? [Y] [N]:\n"); var closeKey = Console.ReadKey(); switch (closeKey.Key) { case ConsoleKey.Y: Environment.Exit(0); break; case ConsoleKey.N: Process.Start(AppDomain.CurrentDomain.FriendlyName); Environment.Exit(0); break; } break; } } } }
额外说明
- 代码中所有时间间隔参数都可以根据实际使用需求调整,避免操作过快被游戏检测
- 若需要实现长按不释放的操作,只需在需要按下的时机发送一次
WM_KEYDOWN消息,需要释放时再发送WM_KEYUP消息即可 - 所有API均为Windows系统原生接口,.NET Core 3.0+版本在Win10环境下可直接运行,不需要额外依赖Windows Forms组件
内容的提问来源于stack exchange,提问作者user14224713
相关产品推荐
相关产品推荐

