6

私が作成しているアプリケーションの場合、外部プロセスからのウィンドウメッセージをインターセプトしたいと思います(spy ++と同じように)。SetWinEventHookを使用してこれを行うことができることがわかりました。これは私が持っているコードです。

    class Program
    {
    internal delegate void WinEventProc(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int      idObject, int idChild, int dwEventThread, int dwmsEventTime);
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr SetWinEventHook(int eventMin, int eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, int idProcess, int idThread, SetWinEventHookFlags dwflags);
        //[DllImport("user32.dll", SetLastError = true)]
        internal static extern int UnhookWinEvent(IntPtr hWinEventHook);
      internal enum SetWinEventHookFlags
      {
          WINEVENT_INCONTEXT = 4,
          WINEVENT_OUTOFCONTEXT = 0,
          WINEVENT_SKIPOWNPROCESS = 2,
          WINEVENT_SKIPOWNTHREAD = 1
      } 
        static void Main(string[] args)
        {
            int threadId = 0x000306D4;
            int processId = 0x000306BC;
            WinEventProc listener = new WinEventProc(EventCallback);
   //setting the window hook and writing the result to the console
            Console.WriteLine(SetWinEventHook(1, 0x7fffffff, IntPtr.Zero, listener, processId, threadId, SetWinEventHookFlags.WINEVENT_INCONTEXT).ToString());
            Console.WriteLine("done");
            Console.ReadKey(); 
        }
        private static void EventCallback(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
        {
   //callback function, called when message is intercepted
            Console.WriteLine(hWnd.ToString());
        }
    }
   }

私の知る限り、正しいP / Invoke宣言を使用していますが、このコードを実行すると、出力は次のようになります。

0
終わり

成功した場合は、このイベントフックインスタンスを識別するHWINEVENTHOOK値を返す必要があります。失敗した場合は0を返します。(少なくともMicrosoftのWebサイトによると)スレッドとプロセスの両方が有効で実行されているようです。

誰かが私の問題がどこにあるかに近づくのを手伝ってもらえますか?私はそれが何か小さなものであるに違いないと思います、あるいは私は自分がやりたいことをするために完全に間違った方法を使っているだけです。前もって感謝します。

4

2 に答える 2

7

msdnによると

コンテキスト外のイベントの場合、イベントはSetWinEventHookと呼ばれるのと同じスレッドで配信されます。

コンソールアプリであなたの例を試しましたが、あなたが言ったように、イベントは受信されませんでした。ただし、WinFormでは、例が機能し、イベントが受信されます。つまり、これはコンソールアプリケーションでの単一スレッドの実行によるものだと思います。

SetWinEventHook呼び出しをボタンクリックイベントに入れると、コールバックでイベントの受信を開始する必要があります。

于 2012-12-11T10:58:59.430 に答える
6

ポイントは少し異なります:

SetWinEventHookを呼び出すクライアントスレッドには、イベントを受信するためのメッセージループが必要です。

MSDN

コンソールアプリケーション内にはメッセージループはありませんが、winformアプリケーション内にはメッセージループがあります。そのため、コンソールアプリでイベントを取得しません。

于 2014-10-17T05:53:02.213 に答える