2009-06-08 9 views
5

多くのことを試してみましたが、私のタスクバーが嫌になったり、デスクトップのUIに他の超自然的な影響が出たりする中で、一貫して動作させることはできません。システムを追加する方法 "ウィンドウフック"は、ウィンドウの作成/アクティブ化を通知するように?

最初のオープンライブラリhttp://mwinapi.sourceforge.net/を使用してみました。それはウィンドウや物を列挙するためのOOレイヤーとしてうまく機能しましたが。これは、適切に

次の停車駅はDino E.'s post on Windows Hooks in the .Net frameworkたフックを行うことができませんでした。テキストを理解してこれを動作させようとしているので、私は自分のタイプを書いてしまいました。

このアプリケーションを実行し、作成したすべてのウィンドウを実行中にログに記録することができます。すべての眼球を呼び出す...

アップデート:どうやらので、切り取らあなたcan't write global windows hooks in .Net /(いくつかの低レベルのマウスやキーボードフックを除く)マネージコードを

は、だから私はC++に切り替えました。それでもすべてのWinAPI呼び出しは有効なハンドルを返しますが、フィルタ機能が呼び出されることはありません。通知を受け取っていないようです。まだ動作しません...誰かが間違いを発見することはできますか?

void CWinHookFacade::Hook() 
{ 
    HMODULE hCurrentDll = LoadLibrary(_T("[Path to my hook dll]")); 
    m_HookHandle = SetWindowsHookEx(WH_CBT, 
     FilterFunctionForHook, 
     hCurrentDll, 
     0); 
    if (m_HookHandle == NULL) 
    { 
     throw new std::exception("Unable to hook"); 
    } 

} 
void CWinHookFacade::Unhook() 
{ 
    if (!UnhookWindowsHookEx(m_HookHandle)) 
    { 
     throw new std::exception("Unhook failed!"); 
    } 
    m_HookHandle = NULL; 
} 

LRESULT CWinHookFacade::FilterFunctionForHook(int code, WPARAM wParam, LPARAM lParam) 
{ 
    if (code >= 0) 
    { 
     switch(code) 
     { 
     case HCBT_CREATEWND: 
      wprintf(_T("Created Window")); 
      break; 
     case HCBT_ACTIVATE: 
      wprintf(_T("Activated Window")); 
      break; 
     case HCBT_DESTROYWND: 
      wprintf(_T("Destroy Window")); 
      break; 
     } 
    } 

    return CallNextHookEx(m_HookHandle, code, wParam, lParam); 
} 

クライアントのexeファイルは、私はあなたがC#でフック関数を実装しようとしているので、あなたが抱えている問題があると思います。この

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CWinHookFacade::Hook(); 
    getchar(); 
    CWinHookFacade::Unhook(); 
} 
+0

明確にするために、SetWindowsHookExは毎回有効なハンドルを返します。誰かがこれを試してみたい場合には、上記のコードには他の依存関係はありません。空のプロジェクトの.csファイルに貼り付けて実行します。 – Gishu

答えて

5

ようHook_DLLを呼び出します。 pinvoke.net's documentationSetWindowsHookEx()に基づいて、これを行うことはできないと言われています。フックプロシージャは、アンマネージDLL内になければなりません。それ以外の場合は、メッセージループを使用してDLLを実行中のすべてのプロセスにロードします。これにより、各プロセスでCLRがロードされて開始されます。これには時間がかかりますが、CLRをすべてのプロセスに注入するのはおそらく最善の方法ではありません。さらに、実行中のCLRがプロセスにすでに存在し、DLLが作成されたものと異なる場合はどうなりますか?

最善のアプローチは、アンマネージC++ DLLにこのコードを移動し、戻ってあなたのアプリケーションにあなたのフックプロシージャによって傍受データを送信するためにプロセス間通信のいくつかの並べ替えを使用することです。

更新

まず、なぜあなたはDLLのHINSTANCEを取得するためにLoadLibrary()を呼び出している、(これはあなたの問題を引き起こし、おそらくではありませんか)?あなたのDLLが既にロードされているので、おそらくGetModuleHandle()に電話する方が良いでしょう。あなたのフックプロシージャが呼び出されない理由については

- どのようにあなたがこれを確認しましたか?システム内のすべてのGUIスレッドをフックしているので、DLLをすべてのGUIプロセスにロードする必要があります。 wprintf()を呼び出した結果は表示されません。これは、他のプロセスに出力を表示するためのコンソールウィンドウがないためです。

DLLが正しくロードされていることを確認するには、プロセスによってロードされたDLLを一覧表示するプログラムを使用します(私はProcess Explorerが好きです)。あなたはFind | [ハンドルまたはDLLの検索]メニュー項目を使用して、DLLの名前を検索します。これは、メッセージループを含むすべてのプロセスに表示されます。

DLLがロードされたことを確認したら、フックが呼び出されているかどうかを確認するために、別のプロセス(メモ帳など)にデバッガを接続し、フック関数にブレークポイントを設定します。それはメッセージがCBTフックに送信されるたびに消えるはずです。デバッガを使用しない場合は、wprintf()OutputDebugString()に変更し、DebugViewのようなユーティリティを実行して結果を監視することができます。

最後に、フック関数は別のプロセスのコンテキストで呼び出されるため、m_HookHandle変数はそこでは有効になりません。 shared data segmentに格納して、DLLのロードされたすべてのインスタンスが同じ値になるようにしてください。

+0

私は注入部品について知っていた - 私のコードをDLLに持っていた。しかし、C#で行うことが不可能であることを知らなかった。明日CPPでこれを試して、それがどのように進むのかを投稿します... ピンボケページのノートセクションを私の危険に晒すのを忘れました。 (私はManagedThreadIDが難しい方法でも動作しないことを発見しました) – Gishu

+0

私を捨てた別のものは、http://mwinapi.sourceforge.net/ライブラリのHookクラスにはctorパラメータ-bGlobalがあり、完全に管理されています。奇妙な... – Gishu

+0

アンマネージドにも切り替わった - まだ動作していないようです。更新された元の質問... – Gishu

3

最後にこれを釘付けにしました。誰かがこれを将来必要とする場合に備えて、blog postと書いています。

関連する問題