每个应用程序运行时SetWinEventHook仅响应一次回调

时间:2017-07-02 22:53:19

标签: c# winapi pinvoke

我有这个类在CTRL + ALT + DEL屏幕可见时监听。当我运行我的应用程序时,它只能工作一次,然后再也不会再回击。偶尔它似乎会导致内存泄漏给我一个GEOG a b A 1 1 A 2 2.5 A 3 4.25 A 4 6.125 A 5 8.0625 A 6 10.03125 B 1 1 B 2 2.5 B 3 4.25 B 4 6.125 B 5 8.0625 C 1 1 C 2 2.5 C 3 4.25 C 4 6.125 C 5 8.0625 。我知道这个异常与这个钩子有关,因为当我删除钩子代码时,它永远不会引发这种异常。

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

System.AccessViolationException

我从Main()中调用这个静态类,如下所示:

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;

1 个答案:

答案 0 :(得分:3)

你是如何使用外部变量的?

尝试将回调存储在静态变量中,以防止它被GCed。像这样:

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

    ...
}