SetWinEventHook仅在每个应用程序运行时命中一次回调 [英] SetWinEventHook Only Hitting Callback Once Per App Run

查看:48
本文介绍了SetWinEventHook仅在每个应用程序运行时命中一次回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个此类,当CTRL + ALT + DEL屏幕可见时,它会侦听.当我运行我的应用程序时,它只能运行一次,然后再也不会打回该回调.有时似乎会导致内存泄漏,并给我System.AccessViolationException.我知道此异常与此钩子有关,因为当我删除钩子代码时,它永远不会引发此异常.

I have this class that listens for when the CTRL + ALT + DEL screen is visible. When I run my app it only works one time then the callback is never hit again. Occasionally it appears to cause a memory leak giving me a System.AccessViolationException. I know this Exception is related to this hook because when I remove the hook code it never raises this exceptions.

我做错了什么?为什么只执行一次回调?

What am I doing wrong? Why would it only execute the callback once?

public static void StartListeningForDesktopSwitch()
{
    SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH, EVENT_SYSTEM_DESKTOPSWITCH,
        IntPtr.Zero, EventCallback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD);
}

public static void EventCallback(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
    //do stuff when secure desktop is shown or hidden
    Log.LogEvent("Info", "Secure Desktop Event", "", "", null);
}

public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);


[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
        hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
    uint idThread, uint dwFlags);

const uint WINEVENT_OUTOFCONTEXT = 0x0000;
const uint WINEVENT_SKIPOWNTHREAD = 0x0001;
const uint EVENT_SYSTEM_DESKTOPSWITCH = 0x0020;

我正在这样从Main()调用此静态类:

I'm calling this static class from Main() like this:

WindowEventHook.StartListeningForDesktopSwitch();

推荐答案

您如何使用外部变量?

请尝试将回调存储在静态变量中,以防止被回收.像这样:

Try storing the callback in a static variable to keep it from being GCed. Like this:

public static class WindowEventHook
{
    private static readonly WinEventDelegate callback = EventCallback;

    public static void StartListeningForDesktopSwitch()
    {
        SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH, EVENT_SYSTEM_DESKTOPSWITCH,
            IntPtr.Zero, callback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD);
    }

    ...
}

这篇关于SetWinEventHook仅在每个应用程序运行时命中一次回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆