gpt4 book ai didi

c# - 全局 Hook 键盘记录器问题

转载 作者:太空狗 更新时间:2023-10-29 20:11:53 25 4
gpt4 key购买 nike

它将当前的 key 记录到文本框,因此它是安全的。

问题问题是当我在虚拟机或我 friend 的笔记本电脑上运行它时,它在按下一定数量的键(随机)后挂起。它在我的中运行得很好。

http://i34.tinypic.com/29o1im8.jpg

class GlobalKeyboardHook
{


#region Definition of Structures, Constants and Delegates

public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);

public struct GlobalKeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}

const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int WM_SYSKEYDOWN = 0x104;
const int WM_SYSKEYUP = 0x105;
const int WH_KEYBOARD_LL = 13;

#endregion

#region Events

public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;

#endregion

#region Instance Variables

public List<Keys> HookedKeys = new List<Keys>();
IntPtr hookHandle = IntPtr.Zero;

#endregion

#region DLL Imports

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int hookID, KeyboardHookProc callback, IntPtr hInstance, uint threadID);

[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]
static extern bool UnhookWindowsHookEx(IntPtr hookHandle);

[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]
static extern int CallNextHookEx(IntPtr hookHandle, int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);




#endregion

#region Public Methods

public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam)
{

if (nCode >= 0)
{
Keys key = (Keys)lParam.vkCode;

if (HookedKeys.Contains(key) == true)
{
KeyEventArgs kea = new KeyEventArgs(key);

if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && KeyUp != null)
{
KeyUp(this, kea);
}
else if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && KeyDown != null)
{
KeyDown(this, kea);
}
if (kea.Handled) return 1;


}
}

return CallNextHookEx(hookHandle, nCode, wParam, ref lParam);
}


public void hook()
{
IntPtr hInstance = LoadLibrary("user32");
hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
}


public void unhook()
{
UnhookWindowsHookEx(hookHandle);
}

#endregion

#region Constructors and Destructors

public GlobalKeyboardHook()
{
hook();
}

~GlobalKeyboardHook()
{
unhook();
}

#endregion

最佳答案

尝试在启用“CallbackOnCollectedDelegate”MDA 的情况下调试您的应用程序(调试 -> 异常 -> 托管调试助手 -> 检查“CallbackOnCollectedDelegate”)。

这里的常见错误是,在设置 Hook 后,GC 会自动收集 Hook 过程的委托(delegate)(它是作为 P/Invoke 编码(marshal)处理的一部分创建到 SetWindowsHookEx)。 GC 回收委托(delegate)后,程序在尝试调用回调时崩溃。这也可以解释随机性。

如果这是您的问题,您会看到如下错误:

A callback was made on a garbage collected delegate of type '...'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.

尝试将您的钩子(Hook)过程作为您类(class)的成员进行引用,例如:

public delegate int KeyboardHookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam);

public int hookProc(int nCode, int wParam, ref GlobalKeyboardHookStruct lParam)
{
// ...
}

public void hook()
{
_hookProc = new KeyboardHookProc(hookProc);
IntPtr hInstance = LoadLibrary("user32");
hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, _hookProc, hInstance, 0);
}

KeyboardHookProc _hookProc;

关于c# - 全局 Hook 键盘记录器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3540572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com