我想利用机器学习来模拟用户的意图,并可能自动执行常见的任务。 为此,我希望能够访问有关用户操作和机器状态的信息。 为此,我目前的想法是,获得Windows消息stream可能是前进的方向。
我希望获得尽可能多的信息,将信息过滤到我想留给机器学习工具的相关信息中。
这将如何完成? (最好用C#)。
请假设我知道如何pipe理和使用这些大量的数据。
任何帮助将不胜感激。
您可以使用SetWindowsHookEx设置低级挂钩来捕获(特定)Windows消息。 具体来说,这些hook-id可能对于监控来说很有趣:
WH_CALLWNDPROC
(4)安装挂钩程序,在系统将消息发送到目标窗口过程之前监视消息。 有关更多信息,请参阅CallWndProc挂钩过程。
WH_CALLWNDPROCRET
(12)安装钩子程序,在目标窗口过程处理消息之后,监视消息。 有关更多信息,请参阅CallWndRetProc挂钩过程。
我已经实现了一段时间,但作为一个例子,我已经发布了我用来钩住特定消息的基类。 (例如,我已经在全局鼠标轮捕捉器中使用它,确保我的winforms应用程序的行为与Internet Explorer相同:滚动光标下方的控件,而不是主动控件。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using Subro.Win32; namespace Subro { /// <summary> /// Base class to relatively safely register global windows hooks /// </summary> public abstract class GlobalHookTrapper : FinalizerBase { [DllImport("user32", EntryPoint = "SetWindowsHookExA")] static extern IntPtr SetWindowsHookEx(int idHook, Delegate lpfn, IntPtr hmod, IntPtr dwThreadId); [DllImport("user32", EntryPoint = "UnhookWindowsHookEx")] private static extern int UnhookWindowsHookEx(IntPtr hHook); [DllImport("user32", EntryPoint = "CallNextHookEx")] static extern int CallNextHook(IntPtr hHook, int ncode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll")] static extern IntPtr GetCurrentThreadId(); IntPtr hook; public readonly int HookId; public readonly GlobalHookTypes HookType; public GlobalHookTrapper(GlobalHookTypes Type):this(Type,false) { } public GlobalHookTrapper(GlobalHookTypes Type, bool OnThread) { this.HookType = Type; this.HookId = (int)Type; del = ProcessMessage; if (OnThread) hook = SetWindowsHookEx(HookId, del, IntPtr.Zero, GetCurrentThreadId()); else { var hmod = IntPtr.Zero; // Marshal.GetHINSTANCE(GetType().modulee); hook = SetWindowsHookEx(HookId, del, hmod, IntPtr.Zero); } if (hook == IntPtr.Zero) { int err = Marshal.GetLastWin32Error(); if (err != 0) OnHookFailed(err); } } protected virtual void OnHookFailed(int Error) { throw Win32Functions.TranslateError(Error); } private const int HC_ACTION = 0; [MarshalAs(UnmanagedType.FunctionPtr)] private MessageDelegate del; private delegate int MessageDelegate(int code, IntPtr wparam, IntPtr lparam); private int ProcessMessage(int hookcode, IntPtr wparam, IntPtr lparam) { if (HC_ACTION == hookcode) { try { if (Handle(wparam, lparam)) return 1; } catch { } } return CallNextHook(hook, hookcode, wparam, lparam); } protected abstract bool Handle(IntPtr wparam, IntPtr lparam); protected override sealed void OnDispose() { UnhookWindowsHookEx(hook); AfterDispose(); } protected virtual void AfterDispose() { } } public enum GlobalHookTypes { BeforeWindow = 4, //WH_CALLWNDPROC AfterWindow = 12, //WH_CALLWNDPROCRET KeyBoard = 2, //WH_KEYBOARD KeyBoard_Global = 13, //WH_KEYBOARD_LL Mouse = 7, //WH_MOUSE Mouse_Global = 14, //WH_MOUSE_LL JournalRecord = 0, //WH_JOURNALRECORD JournalPlayback = 1, //WH_JOURNALPLAYBACK ForeGroundIdle = 11, //WH_FOREGROUNDIDLE SystemMessages = 6, //WH_SYSMSGFILTER MessageQueue = 3, //WH_GETMESSAGE ComputerBasedTraining = 5, //WH_CBT Hardware = 8, //WH_HARDWARE Debug = 9, //WH_DEBUG Shell = 10, //WH_SHELL } public abstract class FinalizerBase : IDisposable { protected readonly AppDomain domain; public FinalizerBase() { System.Windows.Forms.Application.ApplicationExit += new EventHandler(Application_ApplicationExit); domain = AppDomain.CurrentDomain; domain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); domain.DomainUnload += new EventHandler(domain_DomainUnload); } private bool disposed; public bool IsDisposed{get{return disposed;}} public void Dispose() { if (!disposed) { GC.SuppressFinalize(this); if (domain != null) { domain.ProcessExit -= new EventHandler(CurrentDomain_ProcessExit); domain.DomainUnload -= new EventHandler(domain_DomainUnload); System.Windows.Forms.Application.ApplicationExit -= new EventHandler(Application_ApplicationExit); } disposed = true; OnDispose(); } } void Application_ApplicationExit(object sender, EventArgs e) { Dispose(); } void domain_DomainUnload(object sender, EventArgs e) { Dispose(); } void CurrentDomain_ProcessExit(object sender, EventArgs e) { Dispose(); } protected abstract void OnDispose(); /// Destructor ~FinalizerBase() { Dispose(); } } }