SetWinEventHook 每个应用只触发一次回调 运行

SetWinEventHook Only Hitting Callback Once Per App Run

我有这个 class 可以监听 CTRL + ALT + DEL 屏幕何时可见。当我 运行 我的应用程序只运行一次时,回调就再也不会被触发了。有时它似乎会导致内存泄漏,给我一个 System.AccessViolationException。我知道这个异常与这个钩子有关,因为当我删除钩子代码时它永远不会引发这个异常。

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

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() 中调用此静态 class,如下所示:

WindowEventHook.StartListeningForDesktopSwitch();

你是怎么使用外部变量的?

尝试将回调存储在静态变量中以防止其被垃圾回收。像这样:

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);
    }

    ...
}