zoukankan      html  css  js  c++  java
  • 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法

    《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法

    源程序部分代码如下
    系统api

    /// <summary>
    /// 安装钩子的函数
    /// </summary>
    /// <param name="idHook"></param>
    /// <param name="lpfn"></param>
    /// <param name="hInstance"></param>
    /// <param name="threadId"></param>
    /// <returns></returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    /// <summary>
    /// 卸下钩子的函数
    /// </summary>
    /// <param name="idHook"></param>
    /// <returns></returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(int idHook);
    /// <summary>
    /// 下一个钩挂的函数
    /// </summary>
    /// <param name="idHook"></param>
    /// <param name="nCode"></param>
    /// <param name="wParam"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
    
    
    
    
    //定义了一个委托
    public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
    
    
    //定义一个代理
    HookProc KeyboardHookDelegate;
    
    
    /// <summary>
    /// 创建钩子
    /// </summary>
    public void SetHook()
    {
        KeyboardHookDelegate = new HookProc(KeyboardHookProc);
        Process cProcess = Process.GetCurrentProcess();
        ProcessModule cModule = cProcess.MainModule;
        var mh = GetModuleHandle(cModule.ModuleName);
        hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
    }
    
    
    public void UnHook()
    {
        UnhookWindowsHookEx(hHook);
    }
    
    
    /// <summary>
    /// 键盘钩子进程
    /// </summary>
    /// <param name="nCode"></param>
    /// <param name="wParam"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
    {
    //...
    //每到这里就报错
    return CallNextHookEx(hHook, nCode, wParam, lParam);
    }




    经过一番搜索,
    可能的原因是定义的委托给垃圾回收机制给回收了,这导致报告如题错误,网上很多朋友们说,将委托定义为成员变量,可是我的就是成员变量还是出错,还有的说要定义代理,可我使用的就是代理了,还有的朋友们说要定义为静态的,但是似乎在我这里全部都无济于事,与似乎我我分析了一下,
    终于解决了,修改如下

    public void SetHook()
    {
        KeyboardHookDelegate = new HookProc(KeyboardHookProc);
        IntPtr intPtr = Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);
        hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, intPtr, 0);
    }


    原来是获得当前进程,然后获取当前进程的MainModule,再获取MainModule的ModuleName
    最后用反射获取到当前程序集,如果程序没有关闭程序集一直是存在的,然后就解决了。
    也许我上述理解可能有误,如果理解有误,还望大神斧正。


  • 相关阅读:
    Java下载execl表格
    ajax请求下载Execl表
    Spring Boot2.4双数据源的配置
    使用nginx对spring boot项目进行代理
    spring mvc中几种获取request对象的方式
    做开发十年,我总结一些开发经验
    linux基础指令以及权限管理
    ArrayList调用remove(int index)抛出UnsupportedOperationException问题分析以及解决记录
    ubuntu16.06+vsftpd+nginx搭建图片服务器
    RPC框架基础概念理解以及使用初体验
  • 原文地址:https://www.cnblogs.com/ching2009/p/4174406.html
Copyright © 2011-2022 走看看