You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不聚焦目标进程的情况下用C#模拟键盘输入及快捷键?

无需聚焦窗口向其他进程模拟键盘输入(含快捷键)的C#实现

要实现无需聚焦目标窗口即可发送键盘输入(如Ctrl+W),核心思路是直接向目标窗口的消息队列发送键盘消息,而非模拟全局键盘输入。以下是具体实现方案:

关键原理

使用Win32 API的PostMessage函数,将键盘消息(WM_KEYDOWN/WM_KEYUP)直接投递到目标窗口的消息队列,无需激活窗口。这种方式适用于大多数标准Win32桌面应用。

完整代码实现

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

class WindowKeyboardSimulator
{
    private static IntPtr? _targetWindowHandle;

    // 导入Win32 API
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    // 键盘消息与按键常量
    private const uint WM_KEYDOWN = 0x0100;
    private const uint WM_KEYUP = 0x0101;
    private const int VK_CONTROL = 0x11;
    private const int VK_W = 0x57;

    static void Main(string[] args)
    {
        // 替换为目标进程的名称(不含.exe后缀)
        var targetProcess = Process.GetProcessesByName("processName").FirstOrDefault();
        _targetWindowHandle = targetProcess?.MainWindowHandle;

        if (_targetWindowHandle == null)
            throw new Exception("无法找到目标进程的主窗口!");

        // 发送Ctrl+W快捷键
        SendCtrlW(_targetWindowHandle.Value);
    }

    private static void SendCtrlW(IntPtr windowHandle)
    {
        // 若需要发送到窗口内的具体控件(如记事本的编辑框),可先获取子控件句柄
        // IntPtr childHandle = FindWindowEx(windowHandle, IntPtr.Zero, "Edit", null);
        // if (childHandle != IntPtr.Zero) windowHandle = childHandle;

        // 构造按键消息参数:lParam低16位为扫描码,高16位标记按键状态
        // 按下Ctrl键
        PostMessage(windowHandle, WM_KEYDOWN, (IntPtr)VK_CONTROL, (IntPtr)0x001D0001);
        // 按下W键
        PostMessage(windowHandle, WM_KEYDOWN, (IntPtr)VK_W, (IntPtr)0x00110001);
        // 松开W键(高16位最高位设为1表示松开)
        PostMessage(windowHandle, WM_KEYUP, (IntPtr)VK_W, (IntPtr)0xC0110001);
        // 松开Ctrl键
        PostMessage(windowHandle, WM_KEYUP, (IntPtr)VK_CONTROL, (IntPtr)0xC01D0001);
    }
}

重要说明

  1. 控件定位:如果目标应用的输入区域是子控件(如记事本的编辑框、浏览器的地址栏),需要用FindWindowEx获取对应子控件的句柄,再将消息发送给子控件,否则主窗口可能不会响应输入。
  2. 消息参数细节:lParam参数包含按键的扫描码、重复次数和状态标志。松开按键时,必须将高16位的最高位设为0xC0,否则应用可能认为按键一直处于按下状态。
  3. 局限性:部分使用DirectInput或自定义输入处理逻辑的应用(如部分游戏)可能无法响应WM_KEYDOWN/WM_KEYUP消息,这类场景需要使用其他技术(如全局钩子),但全局钩子仍可能需要窗口聚焦。
  4. 进程窗口匹配:部分应用(如Chrome)的每个标签页都是独立窗口,需要找到对应标签页的窗口句柄,而非主进程的主窗口。

内容的提问来源于stack exchange,提问作者MTS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 19:54:55