如何模拟键盘事件(Windows 窗体 .NET)

Windows 窗体提供几个选项,用于以编程方式模拟键盘输入。 本文将简要阐述这些选项。

重要

面向 .NET 7 和 .NET 6 的桌面指南文档正在撰写中。

使用 SendKeys

Windows 窗体提供 System.Windows.Forms.SendKeys 类,用于向活动应用程序发送击键。 可通过两种方法将击键发送到应用程序:SendKeys.SendSendKeys.SendWait。 这两种方法的区别在于,在发送击键时,SendWait 会阻止当前线程,等待响应,而 Send 不会。 有关 SendWait 的详细信息,请参阅将击键发送到其他应用程序

注意

如果你的应用程序旨在用于全球各种键盘,使用 SendKeys.Send 可能会产生不可预知的结果,应当避免。

在后台,SendKeys 使用较旧的 Windows 实现来发送输入,这可能会在新式 Windows 上失败,因为在新式 Windows 上应用程序不使用管理权限运行。 如果较旧的实现失败,代码会自动尝试较新的 Windows 实现来发送输入。 此外,如果 SendKeys 类使用新的实现,在将击键发送到其他应用程序时,SendWait 方法不再阻止当前线程。

重要

如果如论使用何种操作系统,你的应用程序均依赖于一致的行为,则可通过将以下应用程序设置添加至 app.config 文件强制执行 SendKeys 类以使用新的实现。

<appSettings>
  <add key="SendKeys" value="SendInput"/>
</appSettings>

若要强制执行 SendKeys 类以仅使用以前的实现,请改用 "JournalHook"

若要将击键发送到相同的应用程序

调用 SendKeys.Send 类或 SendKeys.SendWait 类的 SendKeys 方法。 指定的击键将由应用程序的活动控件接收。

下面的代码示例使用 Send 来模拟同时按 ALTDOWN 键。 这些击键会导致 ComboBox 控件显示其下拉列表。 此示例假定 Form 具有 ButtonComboBox

private void button1_Click(object sender, EventArgs e)
{
    comboBox1.Focus();
    SendKeys.Send("%+{DOWN}");
}
Private Sub Button1_Click(sender As Object, e As EventArgs)
    ComboBox1.Focus()
    SendKeys.Send("%+{DOWN}")
End Sub

若要将击键发送到不同的应用程序

SendKeys.SendSendKeys.SendWait 方法将击键发送到活动应用程序,该应用程序通常是你从其发送击键的应用程序。 若要将击键发送到其他应用程序,首先需要将其激活。 由于没有可激活其他应用程序的托管方法,所以必须使用本机 Windows 方法聚焦其他应用程序。 下面的代码示例使用平台调用来调用 FindWindowSetForegroundWindow 方法以激活计算器应用程序窗口,然后调用 Send 向计算器应用程序发出一系列计算。

下面的代码示例使用 Send 模拟按下键进入 Windows 10 计算器应用程序。 它首先搜索标题为 Calculator 的应用程序窗口,然后将其激活。 激活后,将发送击键以计算 10 加 10。

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)
{
    IntPtr calcWindow = FindWindow(null, "Calculator");

    if (SetForegroundWindow(calcWindow))
        SendKeys.Send("10{+}10=");
}
<Runtime.InteropServices.DllImport("USER32.DLL", CharSet:=Runtime.InteropServices.CharSet.Unicode)>
Public Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr : End Function

<Runtime.InteropServices.DllImport("USER32.DLL")>
Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean : End Function

Private Sub Button1_Click(sender As Object, e As EventArgs)
    Dim hCalcWindow As IntPtr = FindWindow(Nothing, "Calculator")

    If SetForegroundWindow(hCalcWindow) Then
        SendKeys.Send("10{+}10=")
    End If
End Sub

使用 OnEventName 方法

模拟键盘事件的最简单方法是在引发事件的对象上调用方法。 大多数事件都具有调用这些事件的相应方法,以 On 后跟 EventName 的模式命名,如 OnKeyPress。 这种方式只适用于自定义控件或窗体内,因为这些方法受到保护且不能从控件或窗体的上下文外访问。

这些受保护的方法可用于模拟键盘事件。

  • OnKeyDown
  • OnKeyPress
  • OnKeyUp

有关这些事件的详细信息,请参阅使用键盘事件(Windows 窗体 .NET)

另请参阅