如何在不修改.NET源码的情况下用SendKeys.Send发送F17按键?
解决SendKeys无法发送F17键的替代方案
既然SendKeys只支持F1到F16的功能键,又没法修改.NET源码或绕过它的封装限制,直接用Windows原生的SendInput API是最靠谱的解决办法——这个底层API支持所有标准虚拟键码,包括F17到F24这类SendKeys没覆盖的按键。
以下是C#的实现代码,直接通过P/Invoke调用系统函数,不需要依赖SendKeys:
using System; using System.Runtime.InteropServices; public static class KeyboardInput { // 定义Windows API所需的结构 [StructLayout(LayoutKind.Sequential)] private struct INPUT { public uint Type; public INPUTUNION Data; } [StructLayout(LayoutKind.Explicit)] private struct INPUTUNION { [FieldOffset(0)] public KEYBDINPUT Keyboard; } [StructLayout(LayoutKind.Sequential)] private struct KEYBDINPUT { public ushort Vk; public ushort Scan; public uint Flags; public uint Time; public IntPtr ExtraInfo; } // 常量定义 private const uint INPUT_KEYBOARD = 1; private const uint KEYEVENTF_KEYUP = 0x0002; private const ushort VK_F17 = 0x7E; // F17对应的虚拟键码 // 导入SendInput函数 [DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); // 封装发送F17按键的方法 public static void SendF17() { // 构造按下F17的输入事件 var pressInput = new INPUT { Type = INPUT_KEYBOARD, Data = new INPUTUNION { Keyboard = new KEYBDINPUT { Vk = VK_F17, Flags = 0 } } }; // 构造松开F17的输入事件 var releaseInput = new INPUT { Type = INPUT_KEYBOARD, Data = new INPUTUNION { Keyboard = new KEYBDINPUT { Vk = VK_F17, Flags = KEYEVENTF_KEYUP } } }; // 发送按下+松开的完整按键序列 INPUT[] inputSequence = new[] { pressInput, releaseInput }; SendInput((uint)inputSequence.Length, inputSequence, Marshal.SizeOf(typeof(INPUT))); } }
使用方式
在你的自动化流程里,直接调用KeyboardInput.SendF17()就能模拟一次完整的F17按键操作,替换原来想用SendKeys.Send("{F17}")的地方即可。
额外提示
如果需要确保按键发送到目标遗留客户端窗口,可以在调用SendF17()前,先调用SetForegroundWindow激活目标窗口(同样需要通过P/Invoke导入该函数),避免输入被其他窗口接收。
内容的提问来源于stack exchange,提问作者Djarrah
相关产品推荐
相关产品推荐

