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

WPF .NET Core 6自动化项目:如何向其他进程发送按键?

问题描述

我正在开发一个基于WPF(.NET Core 6)的自动化项目,需要向系统中运行的另一个应用程序发送按键指令。程序启动后会通过后台工作线程循环监听预设按键,检测到按键按下时向目标进程发送指定按键。由于WPF项目限制,无法直接使用System.Windows.Forms及SendKeys.Send("{ENTER}")方法。

已尝试的两种方案均未成功:

  • 使用InputManager:后台线程遇到[STAThread]错误,解决后仍无法成功发送按键,相关代码如下:
public static void Send(Key key)
{
    if (Keyboard.PrimaryDevice != null)
    {
        if (Keyboard.PrimaryDevice.ActiveSource != null)
        {
            var e = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key)
            {
                RoutedEvent = Keyboard.KeyDownEvent
            };
            InputManager.Current.ProcessInput(e);

            // Note: Based on your requirements you may also need to fire events for:
            // RoutedEvent = Keyboard.PreviewKeyDownEvent
            // RoutedEvent = Keyboard.KeyUpEvent
            // RoutedEvent = Keyboard.PreviewKeyUpEvent
        }
    }
}
  • 添加System.Windows.Forms引用:尝试引用后使用SendKeys.SendWait,但Visual Studio无法识别该函数,手动添加引用也未生效。

请问是否存在无需复杂实现的方案,可在WPF .NET Core项目中替代SendKeys.Send的功能?

可行解决方案

1. 使用Windows API的SendInput函数

这是底层且可靠的系统级模拟方式,无需依赖WinForms,直接调用系统API实现按键发送。先导入相关API:

using System;
using System.Runtime.InteropServices;

public static class KeyboardSimulator
{
    [StructLayout(LayoutKind.Sequential)]
    private struct INPUT
    {
        public uint Type;
        public InputUnion Data;
    }

    [StructLayout(LayoutKind.Explicit)]
    private struct InputUnion
    {
        [FieldOffset(0)] public MOUSEINPUT Mouse;
        [FieldOffset(0)] public KEYBDINPUT Keyboard;
        [FieldOffset(0)] public HARDWAREINPUT Hardware;
    }

    [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;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

    public static void SendKey(ushort virtualKeyCode)
    {
        // 模拟按键按下
        INPUT downInput = new INPUT
        {
            Type = INPUT_KEYBOARD,
            Data = new InputUnion
            {
                Keyboard = new KEYBDINPUT
                {
                    Vk = virtualKeyCode,
                    Flags = 0
                }
            }
        };

        // 模拟按键松开
        INPUT upInput = new INPUT
        {
            Type = INPUT_KEYBOARD,
            Data = new InputUnion
            {
                Keyboard = new KEYBDINPUT
                {
                    Vk = virtualKeyCode,
                    Flags = KEYEVENTF_KEYUP
                }
            }
        };

        INPUT[] inputs = new INPUT[] { downInput, upInput };
        SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
    }
}

使用示例(发送回车键):

// VK_RETURN对应回车键的虚拟键码
KeyboardSimulator.SendKey(0x0D);

2. 使用NuGet包InputSimulator

这是封装了SendInput的开源库,使用更简洁,无需手动编写API导入代码:

  1. 安装NuGet包:在NuGet包管理器中搜索InputSimulator并安装,或执行命令 Install-Package InputSimulator
  2. 使用示例:
using WindowsInput;

var simulator = new InputSimulator();
// 发送回车键
simulator.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.RETURN);
// 发送组合键(比如Ctrl+C)
simulator.Keyboard.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.CONTROL, WindowsInput.Native.VirtualKeyCode.VK_C);

3. 正确引用System.Windows.Forms使用SendKeys

如果坚持使用SendKeys,需在.NET Core WPF项目中完成以下配置:

  1. 右键项目→管理NuGet包,安装System.Windows.Forms包
  2. 编辑项目文件(.csproj),添加配置:
<PropertyGroup>
    <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
  1. 使用时需确保在STA线程调用(可通过Dispatcher切换到UI线程):
using System.Windows.Forms;

// 发送回车键
SendKeys.SendWait("{ENTER}");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:52:19