質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Q&A

1回答

13484閲覧

Windows: SetWindowsHookExの奇妙な動作

hirotan

総合スコア12

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

0グッド

3クリップ

投稿2015/03/25 12:59

Windowsの他のアプリ上でのマウス操作をフックするためにSetWindowsHookExを使用しています。
32bit Windows上では32bit版のDLLを作成し、その中でSetWindowsHookExを呼び出すことで期待した動作をすることができていました。

ところが、64bit Windows上で同様のことをやる場合、32bit版のDLLと64bit版のDLLを用意してそれぞれSetWindowsHookExを呼び出すわけですが、コールバックされた関数でGetCurrentProcessId()を使って確認すると、マウス操作をしているアプリのプロセスではなく、DLLをロードした実行ファイルのプロセスになってしまいます。

試しに64bit版DLLのSetWindowsHookExだけを外すと32bitアプリ上では期待通りの動作をします。
また逆に32bit版DLLのSetWindowsHookExだけを外すと64bitアプリ上では期待通りの動作をします。
つまり、64bit/32bit版それぞれのSetWindowsHookExがお互い干渉して期待した動作をしないような感じです。

それぞれのDLLは独立した実行ファイルからロードしたものなのでSetWindowsHookExが干渉することはありえないはずですが、これ以上どのように調べていったらいいのかお手上げ状態です。

詳しい方がいらっしゃいましたらご指導のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

英語の方のSetWindowsHookExのRemarksにはまさにそのことが書かれています。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms644990(v=vs.85).aspx

グローバルフックといっても実際には各プロセスにDLLがインジェクションされるため相手のプロセスとフックのあるDLLのビット数が一致する必要があります。しかし、グローバルフックなのに相手都合でインジェクションされなかったらグローバルじゃねえじゃん、ということでビット数が一致しないプロセスの場合、フックをインストールしたスレッド上で実行されます。

相手のコンテキスト上で動く必要がないなら32ビットアプリのみ作ればOK、ただしスレッドのメッセージループ止めるなよ、ということみたいです。

投稿2015/03/26 12:14

toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hirotan

2015/03/26 14:44

ご回答ありがとうございます。 ご紹介いただいたURLはすでに確認してありますし、実際そのように実装・動作しています。 ただし、32bit/64bitの双方のDLLでSetWindowsHookExすると、コールバックされた関数ではDLLをロードしたプロセスのコンテキストになってしまいます。(ここだけがRemarksの内容と異なる) ちなみにですが、 32bitアプリ上でマウス操作:どちらのコールバックもDLLをロードしたプロセスのコンテキスト 64bitアプリ上でマウス操作:64bit DLLのコールバックは対象アプリのコンテキスト、32bit側はDLLをロードしたプロセス となっており、32bitアプリのときだけ奇妙な動作となってしまいます。 また、フックしたアプリのコンテキスト上で実行する必要があるため、32/64bit両方が必要になっています。
toki_td

2015/03/26 17:54

実際そこがどのように実装されているかはソースは見つかりませんでしたが 32ビット、64ビットともにDLLを名前を変えて2つずつ作成して色々実験してみたら 以下のようなことがわかりました。 1. 32ビットのみ2つ立ち上げ -> 32ビットアプリ上なら対象プロセス内でそれぞれのフックが呼び出される -> 64ビットアプリ上ならフックアプリのどれかのプロセスで実行される これは数を増やしても一緒 2. 64ビットのみ2つ立ち上げ 32ビットの反転バージョンで動作は同じ 3. 32ビットと64ビットを1つずつ立ち上げ 立ち上げる順番によって動作が変わる。 先に立ち上げたほうは常に自身のフックアプリのプロセス 後に立ち上げたほうはビット数のが同じなら対象プロセス内、違う場合はフックアプリ 4. 32ビットと64ビットをそれぞれ2つずつ立ち上げ 3と同じで最後に立ち上げた方のビット数と同じなら対象プロセス内、違う場合は同じビット数のフックアプリ よって、 対象プロセスと最後に設定したフックのビット数が一致する場合は対象プロセス内で動く、 ですべて辻褄が合うようです。 自身以外のフックで経路が変わるのでグローバルフックで すべてのコンテキストに、というのは難しそうですね…
hirotan

2015/03/30 12:49

わざわざ確認していただきありがとうございます。 起動の順序にも依存するようですね。 その線でもう少し詳しく調べてみたいと思います。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問