试图以编程方式按住一个键

Trying to programmatically hold a key down

我正在尝试编写一个应用程序来执行一些基本的流程自动化,方法是将键盘事件(即模拟单键按下和按住)发送到 window 焦点(任何 window,如记事本)。我可以让单键按下工作得很好,但我不能让它按住一个键。即使我执行了一个按键按下事件,然后是长时间的延迟,然后是一个按键……我得到的只是一次按键。

我已经阅读了如此多的教程,并且其中许多都反复阅读了很多遍,以确保我没有遗漏任何内容。然而,每一次,我得到的只是一次按键,它无法按住该键。

以下是我从中找到的代码示例: https://social.msdn.microsoft.com/Forums/vstudio/en-US/bad5b1f3-cf59-4a2b-889b-257ee590bf99/vb-advanced-key-bot?forum=vbgeneral

我期望发生的是它会发送一个键盘事件,告诉系统按住一个键(例如 aaaaaaaaaaaaaaaaaaa),但我得到的只是一个字符。我曾尝试通过重复按键向系统发送垃圾邮件,但接收应用程序看到按键和按键的不同键盘代码,而不是处于保持状态的按键,因此没有响应,就好像按键实际上被按下了一样。

我做错了什么?他们可能更改了这个 dll 吗?

非常感谢任何能帮助我完成这项工作的人。

Public Class Form1
    Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
    Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Integer, ByVal wMapType As Integer) As Integer

    ' flag to indicate completion
    Dim finished As Boolean = True

    ' how long to 'press' the Space key
    Dim delay As Integer = 3

    ' how many times to repeat Q and Space
    Dim Repeats As Integer

    ' User closes application during processing
    Dim UserInterupt As Boolean = False

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        KeyPreview = True
    End Sub
    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If Not finished Then
            TextBox1.AppendText("USER closing" & vbCrLf)
            UserInterupt = True
            e.Cancel = True
        End If
    End Sub
    Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
        Select Case e.KeyChar
            Case "z", "Z"
                e.Handled = True
                Repeats = 12
                finished = False
                Do While Not finished
                    TextBox1.AppendText("Pressing SPACE" & vbCrLf)
                    HoldKeyDown(Keys.Space, delay)
                Loop
            Case "x", "X"
                e.Handled = True
                TextBox1.AppendText("USER stopping" & vbCrLf)
                finished = True
        End Select
    End Sub
    Private Sub HoldKeyDown(ByVal k As Keys, ByVal Hold As Integer)
        Dim HoldFor As DateTime = DateTime.Now().AddSeconds(Hold)
        keybd_event(k, MapVirtualKey(k, 0), 0, 0)
        While HoldFor.Subtract(DateTime.Now()).TotalSeconds > 0
            Application.DoEvents()
        End While
        keybd_event(k, MapVirtualKey(k, 0), 2, 0)
        TextBox1.AppendText("SPACE released" & vbCrLf)
        Repeats -= 1
        If Repeats = 0 Then
            finished = True
            TextBox1.AppendText("REPEATS completed" & vbCrLf)
        End If
        If UserInterupt Then End
    End Sub
End Class

在进入这个问题的兔子洞后回答我自己的问题。

基本上,唯一的方法就是使用 SendKeys。其他方法都已弃用,因此将不再以这种方式工作。

然而,这不适合您 dead-end。如果您想使用 SendKeys 来“按住”一个键,则以 10 毫秒的间隔向该键发送垃圾邮件,这应该会触发接收应用认为该键已被按下。