Vb.net 如何在后台监听键盘并按需击键?

Vb.net 如何在后台监听键盘并按需击键?,vb.net,visual-studio-2008,keystroke,keyboard-hook,keystrokes,Vb.net,Visual Studio 2008,Keystroke,Keyboard Hook,Keystrokes,我想在vb.NET2008中制作一个程序,它将在后台监听键盘,即即使应用程序被最小化(全局)。如果用户按了一个特定的键,它应该以固定的给定时间间隔继续触发另外两个键,直到用户再次按该特定键为止 如何在vb.NET 2008中实现这一点?来源: 用法: 创建钩子的步骤 Private WithEvents kbHook As New KeyboardHook 然后可以处理每个事件: Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Fo

我想在vb.NET2008中制作一个程序,它将在后台监听键盘,即即使应用程序被最小化(全局)。如果用户按了一个特定的键,它应该以固定的给定时间间隔继续触发另外两个键,直到用户再次按该特定键为止

如何在vb.NET 2008中实现这一点?

来源: 用法: 创建钩子的步骤

Private WithEvents kbHook As New KeyboardHook
然后可以处理每个事件:

Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
    Debug.WriteLine(Key.ToString) 
End Sub 
Private Sub kbHook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyUp 
    Debug.WriteLine(Key) 
End Sub
键盘挂钩类别:

Imports System.Runtime.InteropServices

Public Class KeyboardHook

    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As UInt32
        Public scanCode As UInt32
        Public flags As KBDLLHOOKSTRUCTFlags
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure

    <Flags()> _
    Private Enum KBDLLHOOKSTRUCTFlags As UInt32
        LLKHF_EXTENDED = &H1
        LLKHF_INJECTED = &H10
        LLKHF_ALTDOWN = &H20
        LLKHF_UP = &H80
    End Enum

    Public Shared Event KeyDown(ByVal Key As Keys)
    Public Shared Event KeyUp(ByVal Key As Keys)

    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const HC_ACTION As Integer = 0
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105

    Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

    Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
    Private HHookID As IntPtr = IntPtr.Zero

    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        If (nCode = HC_ACTION) Then
            Dim struct As KBDLLHOOKSTRUCT
            Select Case wParam
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
                Case WM_KEYUP, WM_SYSKEYUP
                    RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
            End Select
        End If
        Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
    End Function

    Public Sub New()
        HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        If HHookID = IntPtr.Zero Then
            Throw New Exception("Could not set keyboard hook")
        End If
    End Sub

    Protected Overrides Sub Finalize()
        If Not HHookID = IntPtr.Zero Then
            UnhookWindowsHookEx(HHookID)
        End If
        MyBase.Finalize()
    End Sub

End Class
导入System.Runtime.InteropServices
公共类键盘钩
_
Private将共享函数SetWindowsHookEx(ByVal idHook作为整数,ByVal HookProc作为KBDLLHookProc,ByVal hInstance作为IntPtr,ByVal wParam作为整数)重载为整数
端函数
_
私有重载共享函数CallNextHookEx(ByVal idHook作为整数,ByVal nCode作为整数,ByVal wParam作为IntPtr,ByVal lParam作为IntPtr)作为整数
端函数
_
私有重载共享函数unhookwindowshookx(ByVal idHook作为整数)作为布尔值
端函数
_
私有结构KBDLLHOOKSTRUCT
公共vkCode作为UInt32
公共扫描代码为UInt32
作为KBDLLHOOKSTRUCTFlags的公共标志
公共时间为UInt32
公共dwExtraInfo作为UIntPtr
端部结构
_
私有枚举KBDLLHOOKSTRUCTFlags作为UInt32
LLKHF_扩展=&H1
LLKHF_注入=&H10
LLKHF_ALTDOWN=&H20
LLKHF_UP=&H80
结束枚举
公共共享事件KeyDown(ByVal键作为键)
公共共享事件密钥(ByVal密钥作为密钥)
私有常量WH\u键盘LL为整数=13
私有常量HC_操作为整数=0
私有常量WM_KEYDOWN=&H100
私有常量WM_KEYUP=&H101
私有常量WM_SYSKEYDOWN=&H104
私有常量WM_SYSKEYUP=&H105
私有委托函数KBDLLHookProc(ByVal nCode作为整数,ByVal wParam作为IntPtr,ByVal lParam作为IntPtr)作为整数
私有KBDLLHookProc委托为KBDLLHookProc=新的KBDLLHookProc(KeyboardProc的地址)
私有HHookID作为IntPtr=IntPtr.Zero
私有函数KeyboardProc(ByVal nCode作为整数,ByVal wParam作为IntPtr,ByVal lParam作为IntPtr)作为整数
如果(nCode=HC\U动作),则
作为KBDLLHOOKSTRUCT的Dim结构
选择案例wParam
案例WM\U KEYDOWN,WM\U SYSKEYDOWN
RaiseEvent键关闭(CType(CType(Marshal.PtrToStructure(lParam,struct.GetType()),KBDLLHOOKSTRUCT.vkCode,键))
案例WM\U KEYUP,WM\U SYSKEYUP
RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam,struct.GetType()),KBDLLHOOKSTRUCT.vkCode,键))
结束选择
如果结束
Return CallNextHookEx(IntPtr.Zero、nCode、wParam、lParam)
端函数
公共分新()
HHookID=SetWindowsHookEx(WH_KEYBOARD,kbdllhookprocedelegate,System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.getexecutinggassembly.GetModules()(0)).ToInt32,0)
如果HHookID=IntPtr.Zero,则
抛出新异常(“无法设置键盘挂钩”)
如果结束
端接头
受保护的覆盖子完成()
如果不是HHookID=IntPtr.Zero,则
胡克(胡克)
如果结束
MyBase.Finalize()
端接头
末级

如果使用KeyboardHook类,请确保在使用之前必须构建程序。关于特定密钥的问题,您可以在KeyDown或KeyUp事件中触发它。但在此之前,您必须使用sendkeys将密钥发送到活动窗口

SendKeys.Send(“L”)将字母L发送到活动窗口

然后您可以执行以下代码;下面检查是否按下字母“a”

Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
    Debug.WriteLine(Key.ToString) 
    if Key.ToString() = "a" then
     'trigger your sendkeys
    end if
End Sub 
要触发开关按钮之类的特定键,只需声明一个布尔变量来检查按钮是否被切换。您可以全局声明它:

变光开关为布尔值=假

只需更新设置条件以检查按下的字母的区域。它将如下所示:

if Key.ToString() = "a" then
  if switch = false then
    switch = true
    'trigger send keys
  else
    switch = false
    'deactivate send keys
  end if
end if

要在发送按键时有一个特定的时间,请使用定时器。我希望这能有所帮助。

是的,这是可能的。但为什么要这样做。我发现无法设置键盘挂钩错误。怎么了?代码运行得很好。但是您必须Project->[Project Name]Properties->Debug->取消选中“Enable the Visual Studio hosting process”,因为它会在您的程序之前拦截挂接的消息。您好,我正在尝试使用以下代码执行一个命令
Private Sub kbHook\u KeyDown(ByVal键为System.Windows.Forms.Keys)处理kbHook.KeyDown Debug.WriteLine(Key.ToString)如果Key.ToString()为“A”,则处理DF1Com1.Write(“O:1/0”,“1”)如果End Sub结束,则结束,但它不起作用。有什么我做错了吗?我得到了无法设置键盘挂钩异常,visual studio 2017,禁用托管进程的选项不存在