Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 钩子最小化第三方应用程序的事件_C#_.net_Winapi_Hook_Pinvoke - Fatal编程技术网

C# 钩子最小化第三方应用程序的事件

C# 钩子最小化第三方应用程序的事件,c#,.net,winapi,hook,pinvoke,C#,.net,Winapi,Hook,Pinvoke,我有以下几门课: public sealed class Hook : IDisposable { public delegate void Win32Event(IntPtr hWnd); #region Windows API private const uint WINEVENT_OUTOFCONTEXT = 0x0000; [DllImport("User32.dll", SetLastError = true)] private stat

我有以下几门课:

public sealed class Hook : IDisposable
{
    public delegate void Win32Event(IntPtr hWnd);

    #region Windows API

    private const uint WINEVENT_OUTOFCONTEXT = 0x0000;


    [DllImport("User32.dll", SetLastError = true)]
    private static extern IntPtr SetWinEventHook(
        uint eventMin,
        uint eventMax,
        IntPtr hmodWinEventProc,
        WinEventDelegate lpfnWinEventProc,
        uint idProcess,
        uint idThread,
        uint dwFlags);


    [DllImport("user32.dll")]
    private static extern bool UnhookWinEvent(
        IntPtr hWinEventHook
        );

    private enum SystemEvents : uint
    {
        EVENT_OBJECT_CREATE = 0x8000,
        EVENT_OBJECT_DESTROY = 0x8001,
        EVENT_SYSTEM_MINIMIZESTART = 0x0016,
        EVENT_SYSTEM_MINIMIZEEND = 0x0017,
        EVENT_SYSTEM_FOREGROUND = 0x0003
    }

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

    #endregion

    public Win32Event OnWindowCreate = delegate { };
    public Win32Event OnWindowDestroy = delegate { };
    public Win32Event OnWindowForegroundChanged = delegate { };
    public Win32Event OnWindowMinimizeEnd = delegate { };
    public Win32Event OnWindowMinimizeStart = delegate { };
    private IntPtr pHook;
    private bool _disposed;


    public Hook(IntPtr hWnd)
    {
        pHook = SetWinEventHook((uint) SystemEvents.EVENT_SYSTEM_FOREGROUND,
                                (uint) SystemEvents.EVENT_OBJECT_DESTROY,
                                hWnd,
                                WinEvent,
                                0,
                                0,
                                WINEVENT_OUTOFCONTEXT
            );
        if (IntPtr.Zero.Equals(pHook))
            throw new Win32Exception();
    }

    public void Dispose()
    {
        Dispose(true);
    }


    private void WinEvent(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild,
                          uint dwEventThread, uint dwmsEventTime)
    {
        switch ((SystemEvents) eventType)
        {
            case SystemEvents.EVENT_OBJECT_DESTROY:
                OnWindowDestroy(hWnd);
                break;

            case SystemEvents.EVENT_SYSTEM_FOREGROUND:
                OnWindowForegroundChanged(hWnd);
                break;

            case SystemEvents.EVENT_SYSTEM_MINIMIZESTART:
                OnWindowMinimizeStart(hWnd);
                break;

            case SystemEvents.EVENT_SYSTEM_MINIMIZEEND:
                OnWindowMinimizeEnd(hWnd);
                break;

            case SystemEvents.EVENT_OBJECT_CREATE:
                OnWindowCreate(hWnd);
                break;
        }
    }


    ~Hook()
    {
        Dispose(false);
    }

    private void Dispose(bool manual)
    {
        if (_disposed)
            return;
        if (!IntPtr.Zero.Equals(pHook))
            UnhookWinEvent(pHook);

        pHook = IntPtr.Zero;
        OnWindowCreate = null;
        OnWindowDestroy = null;
        OnWindowForegroundChanged = null;
        OnWindowMinimizeStart = null;
        OnWindowMinimizeEnd = null;
        _disposed = true;

        if (manual)
        {
            GC.SuppressFinalize(this);
        }
    }
}
但当我使用它时,什么也不会发生:

class Program
{
    static void Main(string[] args)
    {
        var process = Process.GetProcessesByName("Notepad")[0];
        var hook = new Hook(process.MainWindowHandle);
        hook.OnWindowMinimizeStart += wnd => Console.WriteLine("Minimized at {0}", DateTime.Now.ToShortTimeString());
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

我做错了什么?看起来一切正常。

您可以从控制台应用程序调用此功能,但是“调用SetWinEventHook的客户端线程必须有一个消息循环才能接收事件。”将其粘贴到forms应用程序中,它就会正常工作。您是对的。改成winforms对我很有效。不幸的是,似乎无法在控制台应用程序中运行它。类似于
System.Windows.Forms.application.run(new System.Windows.Forms.Form())
在控制台应用程序中的钩子调用将用于设置循环后,操作系统不关心您是否创建了控制台模式应用程序,它只关心您是否专用一个线程来泵送消息循环。示例代码。