C# 全局钩子键盘记录器问题

C# 全局钩子键盘记录器问题,c#,hook,global,keylogger,C#,Hook,Global,Keylogger,它将当前的密钥记录到textbox,以确保其安全 问题 问题是当我在虚拟机或我朋友的笔记本电脑上运行时, 按了一定数量的键(随机)后它就会挂起来。在我的电脑里它运行得非常好 类GlobalKeyboardHook { #结构、常量和委托的区域定义 公共委托int KeyboardHookProc(int nCode,int wParam,ref GlobalKeyboardHookStruct lParam); 公共结构GlobalKeyboardHookStruct { 公共int-vkCo

它将当前的密钥记录到textbox,以确保其安全

问题 问题是当我在虚拟机或我朋友的笔记本电脑上运行时, 按了一定数量的键(随机)后它就会挂起来。在我的电脑里它运行得非常好

类GlobalKeyboardHook
{
#结构、常量和委托的区域定义
公共委托int KeyboardHookProc(int nCode,int wParam,ref GlobalKeyboardHookStruct lParam);
公共结构GlobalKeyboardHookStruct
{
公共int-vkCode;
公共int扫描码;
公共国旗;
公共整数时间;
公共信息;
}
常量int WM_KEYDOWN=0x100;
常量int WM_KEYUP=0x101;
常量int WM_SYSKEYDOWN=0x104;
常量int WM_SYSKEYUP=0x105;
const int WH_键盘LL=13;
#端区
#地区活动
公共事件KeyEventHandler KeyDown;
公共事件KeyEventHandler KeyUp;
#端区
#区域实例变量
public List HookedKeys=新列表();
IntPtr hookHandle=IntPtr.Zero;
#端区
#区域DLL导入
[DllImport(“kernel32.dll”)]
静态外部IntPtr加载库(字符串lpFileName);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall,SetLastError=true)]
静态外部IntPtr SetWindowsHookEx(int hookID、KeyboardHookProc回调、IntPtr hInstance、uint threadID);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall,SetLastError=true)]
静态外部bool unhookwindowshookx(IntPtr hookHandle);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
静态extern int CallNextHookEx(IntPtr hookHandle、intncode、intwparam、ref GlobalKeyboardHookStruct lParam);
#端区
#区域公共方法
公共int-hookProc(int-nCode、int-wParam、ref-GlobalKeyboardHookStruct lParam)
{
如果(nCode>=0)
{
Keys key=(Keys)lParam.vkCode;
if(HookedKeys.Contains(key)==true)
{
KeyEventArgs kea=新的KeyEventArgs(key);
if((wParam==WM|KEYUP | wParam==WM|SYSKEYUP)&&KEYUP!=null)
{
KeyUp(这个,kea);
}
else if((wParam==WM|KEYDOWN | wParam==WM|SYSKEYDOWN)&&KEYDOWN!=null)
{
KeyDown(这个,kea);
}
如果(kea.处理)返回1;
}
}
返回CallNextHookEx(hookHandle、nCode、wParam、ref lParam);
}
公共空钩()
{
IntPtr hInstance=LoadLibrary(“user32”);
hookHandle=SetWindowsHookEx(WH_KEYBOARD_LL,hookProc,hInstance,0);
}
公共空间取消挂钩()
{
解开钩柄(钩柄);
}
#端区
#区域构造函数和析构函数
公共GlobalKeyboardHook()
{
钩子();
}
~GlobalKeyboardHook()
{
解开钩();
}
#端区

尝试在“CallbackOnCollectedDelegate”MDA打开的情况下调试应用程序(调试->异常->托管调试助手->选中“CallbackOnCollectedDelegate”)

这里常见的错误是,在设置钩子后,GC会自动收集钩子过程的委托(它是作为p/Invoke封送的一部分创建到
SetWindowsHookEx
)。GC收集委托后,程序在尝试调用回调时崩溃。这也解释了随机性

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

对垃圾进行了回调 已收集类型为“…”的委托。 这可能会导致应用程序崩溃, 损坏和数据丢失。传递时 委托给非托管代码时,它们必须 被管理者维持生命 应用程序,直到它得到保证 他们永远不会被召唤

尝试在类中作为成员保留对钩子过程的引用,例如:

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;

你能说得更具体一点吗?比如,它挂在哪里,什么时候?有错误消息吗?你能用一个复制问题的最小代码示例来编辑你的问题吗?并试着把它变成一个问题。先生,似乎没有运行时错误。所以我不知道代码的哪一部分导致了问题。看看我链接的文件。我t有错误图片->“键盘记录器没有响应”。好的,你可以附加一个调试器并中断进程以查看它所在的位置。链接指向一些正在下载的zip文件。如果你想让别人费心阅读,你需要使阅读问题变得更容易。编辑问题,插入图片和相关代码部分。如果你不知道哪些部分相关,你可以为q编写大量代码uestion。然后,您需要将代码简化到最低限度,以重现您的问题。是否愿意接受答案?它可以帮助有类似问题的其他人,并鼓励其他人参与。谢谢:)
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;