HOME  >  スポンサー広告 >  プログラミング >  グローバルフック(システムフック)でハマったところ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
--/--/-- | カテゴリ:スポンサー広告 | トラックバック(-) | コメント(-)

グローバルフック(システムフック)でハマったところ

Hit a Hint for Windows を作成していて一番ハマったのが
グローバルフック(システムフック)しているのに、ウィンドウメッセージが送られてこない
という現象が発生したことでした。

以下の 2点でハマりました。
  1. 64bit プロセス上からのフックでは、32bit 上プロセスのウィンドウメッセージが取得不可(逆もまた同じ)
  2. Windows Vista 以降の場合、ウィンドウメッセージが一部フィルタリングされる

1. の対処法

64bit 環境の場合は、64bit と 32bit 両方のプロセスからフックしてあげる必要があります。
下記サイトが参考になります。
monoの開発ブログ - 64bit対応なフックを使ったアプリの作り方

2. の対処法

下記 API を使用して、フィルタの設定を変更する必要があります。
Vista : ChangeWindowMessageFilter
7 以降 : ChangeWindowMessageFilterEx
下記が参考になります。
Windows Vista® および Windows Server® 2008 アプリケーション互換性解説書

※ XP、Vista、7 とマルチで使えるアプリケーションを作成したい場合は注意
例えば、XP の場合は上記 API が実装されていないため、単純に呼び出すことができません。
そのため、実行時ロード(LoadLibrary)を使って、ChangeWindowMessageFilter が呼び出せるのであれば呼び、
無ければ呼ばないというように実装する必要があります。

この辺の実装例は、眠いのでまた明日に。
2013/09/27 | カテゴリ:プログラミング | トラックバック(0) | コメント(2)
 32/64ビット両用フック
私もこの問題で1ヶ月くらい格闘しました。
結論を言うと、「グローバルフックはDLLでしか実装できない」は間違いです。
ある方法を使うと、DLLを使わない単独のプロセス(exeファイル)で
32/64のいずれのイベントもフックできます。
私の場合は低レベルキーボードフックですが、64ビットのcmd.exeから
起動した32ビットプロセスでこのcmd.exeのキーボードイベントをフック
できています。
因みに64ビットのプロセスで同様に32ビットプロセスのフックもできました。

ある方法とはメッセージループです。ウィンドウを持たなくても
メッセージループはできますので、試してみてください。
当然ですが、メインの機能は別スレッドで実行しなければなりません。
[ 2017/03/01 22:24 ] [ 編集 ]
 Re: 32/64ビット両用フック
コメントありがとうございます。

使用している環境,プログラミング言語などがわからないので,一般的な話にします。

一般的には,「グローバルフックはDLLでしか実装できない」は正しいです。

SetWindowsHookEx では,グローバルフックするには,パラメータ dwThreadId に 0 を指定します。
そしてパラメータ lpfn の説明は,以下の通りです。

引用:
"dwThreadID パラメータで 0、またはほかのプロセスが作成したスレッドの識別子を指定した場合、
lpfn パラメータで、ダイナミックリンクライブラリ(DLL)内に存在するフックプロシージャへの
ポインタを指定しなければなりません。"

SetWindowsHookEx 関数
https://msdn.microsoft.com/ja-jp/library/cc430103.aspx
SetWindowsHookEx function (Windows)
https://msdn.microsoft.com/ja-jp/library/ms644990%28v=vs.85%29.aspx

# 日本語訳だとわかりにくい表現(誤訳?)があるので英語のページも記載しておきます。


> 結論を言うと、「グローバルフックはDLLでしか実装できない」は間違いです。

この結論は,「.NET Framework を使用している場合で,
ローレベルフック(WH_KEYBOARD_LL,WH_MOUSE_LL)を使用する場合」に限定すると正しいです。
以下のページに記載があります。

引用:
"WH_KEYBOARD_LL の低レベルのフックと WH_MOUSE_LL の低レベルのフックを除いては、
Microsoft.NET Framework のグローバル フックを実装できません。
グローバル フックをインストールするには、フックに有効で一貫性のある関数の呼び出しを
必要とする別のプロセスでそれ自体を挿入するためのネイティブ DLL エクスポートする必要があります。"

Visual C# .NET では、ウィンドウ フックを設定する方法
https://support.microsoft.com/ja-jp/help/318804/how-to-set-a-windows-hook-in-visual-c-.net
How to set a Windows hook in Visual C# .NET
https://support.microsoft.com/en-us/help/318804/how-to-set-a-windows-hook-in-visual-c-.net

利便性のために,これらは例外的にフックできるようにしてあるのかもしれませんね。
64,32 ビットプロセスのフックについての一般的な内容については,以下も参考になります。

WOW64 実装の詳細 (Windows)
https://msdn.microsoft.com/ja-jp/library/aa384274%28v=vs.85%29.aspx
WOW64 Implementation Details (Windows)
https://msdn.microsoft.com/library/aa384274%28v=vs.85%29.aspx

[ 2017/03/02 22:49 ] [ 編集 ]
コメントの投稿












管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
http://uisteven.blog.fc2.com/tb.php/3-1cba5913

外部リンク

カンパのお願い
公開しているソフトウェアはフリーウェアなので無料でご利用いただけます。 気に入ってくださった方は、Amazon でお買い物をする際に下記のリンクを経由して頂ければ励みになります。

検索BOX・タグ一覧
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。