2012-07-06 118 views
5

我想利用機器學習來模擬用戶的意圖,並可能自動執行常見任務。爲此,我想訪問有關用戶操作和機器狀態信息的消防軟管。爲此,我目前的想法是,獲得對Windows消息流的訪問可能是前進的方向。捕獲所有Windows消息

我希望獲得儘可能多的信息,將信息過濾爲我想留給機器學習工具的相關信息。

這將如何實現? (最好用C#)。

請假設我知道如何管理和使用這些大量的數據。

任何幫助將不勝感激。

+0

C#無法做到這一點。 C++可以。 – Alex 2012-07-06 12:02:51

+0

@alex - 爲什麼不能c#能夠做到這一點? – 2012-07-06 12:03:35

+0

@ DanielA.White據我所知,平臺消息隊列只能用本地代碼處理,所以它聽起來不像C#可以做到的那樣(被管理和所有)......我會更高興如果我錯了,所以如果你知道有不同的感覺可以與我相抗衡(我一直在研究這個話題,但是這個話題已經有一段時間了) – Alex 2012-07-06 12:10:48

回答

14

您可以使用SetWindowsHookEx設置低級掛鉤來捕獲(特定)Windows消息。 具體這些鉤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().Module); 
       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(); 
     } 
    } 


} 
+1

非常好,謝謝:) – Marcus 2012-07-06 15:33:11

+0

令人驚歎的男人.... – 2017-06-30 00:21:36