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())
在控制台应用程序中的钩子调用将用于设置循环后,操作系统不关心您是否创建了控制台模式应用程序,它只关心您是否专用一个线程来泵送消息循环。示例代码。