2012-07-06 15 views
5

Desidero sfruttare l'apprendimento automatico per modellare l'intento di un utente e potenzialmente automatizzare le attività eseguite comunemente. Per fare ciò, vorrei avere accesso a una manichetta antincendio di informazioni sulle azioni dell'utente e sullo stato della macchina. A tal fine, è mia opinione attuale che l'accesso al flusso di messaggi di Windows sia probabilmente la strada da seguire.Cattura tutti i messaggi di Windows

Mi piacerebbe avere quante più informazioni possibili, filtrando le informazioni a ciò che è pertinente vorrei lasciare allo strumento di apprendimento automatico.

Come sarebbe stato realizzato? (Preferibilmente in C#).

Si supponga di sapere come gestire e utilizzare questo grande flusso di dati.

Qualsiasi aiuto sarebbe gradito.

+0

C# non può farlo. C++ può. – Alex

+0

@alex - perché non C# è in grado di farlo? –

+0

@ DanielA.White La coda dei messaggi della piattaforma può essere gestita solo in codice nativo per quanto ho capito, quindi non sembra che C# possa farlo (essendo gestito e tutto) ... Sarei più che felice se mi fossi sbagliato quindi se conosci diversi, sentiti libero di contraddirmi (non ho svolto ricerche sull'argomento per un po 'di tempo) – Alex

risposta

14

È possibile utilizzare SetWindowsHookEx per impostare i ganci di livello basso per catturare i messaggi di Windows (specifici). In particolare questi allacci ids potrebbe essere interessante per il monitoraggio:

WH_CALLWNDPROC (4) installa una routine di hook che controlla i messaggi prima che il sistema li invia alla routine della finestra di destinazione. Per ulteriori informazioni su , vedere la procedura di hook CallWndProc.

WH_CALLWNDPROCRET (12) installa una routine di hook che controlla messaggi dopo che sono stati elaborati dal finestrino destinazione procedura. Per ulteriori informazioni, consultare la procedura CallWndRetProc hook .

È passato un po 'di tempo da quando l'ho implementato, ma ad esempio ho pubblicato la classe base che uso per agganciare messaggi specifici. (Ad esempio, l'ho usato in un trapper globale della rotellina di mouse, che assicura che le mie app winforms si comportino allo stesso modo di internet explorer: fai scorrere il controllo sotto il cursore, invece del controllo attivo).

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

Eccellente, grazie :) – Marcus

+0

Uomo incredibile .... –

Problemi correlati