- - PR -
C# グローバルフックでメッセージを編集して送り返す。
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-01-26 14:35
>Microsoft.NET Frameworkではね。
>なるほどー、明言しちゃってるから例外があることは分からないですね。 上記発言を踏まえたうえで確認したいんですが、 C#でグローバル フックすることは可能ということですか? 確かに最近サンプルソースを見かけることがありますので、 気になってはいたのですが... 『C++でAPIプログラムするのに比べて制約がある!?』 というレベルなのでしょうか? あるいは、『グローバル フックは .NET Framework ではサポートされていない』 は、つまりC#でもpInvokeで可能というニュアンスですか!? 【MSサイトより抜粋】 >DLL エクスポートは、.NET Framework でサポートされていません。 >関数ポインタは動的にビルドされるプロキシであるため、 >マネージ コードには関数ポインタの一貫した値の概念がありません。 この説明読むと、『CLRで処理されるプログラムでは不可能なのでは!?』 とも思いますし... どういうことなんでしょうか? | ||||||||||||
|
投稿日時: 2007-01-26 19:33
このスレッドの最小の方で「低レベルフックなら可能」と書きました。
このスレッドをまとめて読めば分かると思いますが ・低レベルフックのみ可能 ・低レベルフックではメッセージの置換は出来ない ・低レベルフックでもメッセージの伝播を絶つことは可能 ということになります。 メッセージ置換が目的の場合も多いと思いますが、そういう用途には「使えない」ことになります。
私見ですが、これもかなり大雑把で表面的な説明だと思います。 これ「だけ」が問題ではないし、これが最も大きな問題だとは思いません。 少なくとも、C++/CLI を使えばこの部分の制限は回避することが出来ます。 個人的には、「同一プロセス内に異なるバージョンの .NET Framework ランタイムは同居できない」ことの方が、グローバルフックを行う上での大きな障害だと考えています。 | ||||||||||||
|
投稿日時: 2007-01-26 22:35
それのことです、できないって言われてしまっては…と。
でもできるのがLow Levelのマウスフック・キーボードフックなんで結局できないみたいな紋ですがね(汗。 Low LevelだとやりたいことができないようなのでC++/CLIでフックの部分だけ書くことにしました。 お騒がせしました m(_ _)m _________________ 有末 清華 crazy(){for;;{you();}} - プログラマの覚書 | ||||||||||||
|
投稿日時: 2007-01-26 22:39
ん? C++じゃなきゃだめかな???
まぁまずは自分でいろいろ調べてから。 C#でフックをしたい方のためのリンク。 http://www.codeproject.com/csharp/globalhook.asp - LLを使ってc#でフック処理 http://www.codeproject.com/csharp/GlobalSystemHook.asp - Unmanaged C++ でやるっぽい…詳細はまだちゃんと見てないから不明。 _________________ 有末 清華 crazy(){for;;{you();}} - プログラマの覚書 | ||||||||||||
|
投稿日時: 2007-01-26 22:49
キケンですよ。 フック DLL を .NET ランタイムとリンクしては駄目です。 理由は簡単、すぐ上で書いたように「同一プロセス内に異なるバージョンの .NET Framework ランタイムは同居できない」からです。 | ||||||||||||
|
投稿日時: 2007-01-26 23:30
うぅーん。 ではC#では低レベルマウス処理以外のフックは基本的にできない(推薦されない)ということですよね。
さてこまったな(汗。 _________________ 有末 清華 crazy(){for;;{you();}} - プログラマの覚書 | ||||||||||||
|
投稿日時: 2007-01-26 23:34
だそうです。だから先のリンク先ではDll二個作ってますね、話さらっと読んだ感じ。 Unmanaged C++とManaged C++の二つを作ってC#でManaged C++側を読み込んでいるんじゃないかな(あとでソース落として確認します) _________________ 有末 清華 crazy(){for;;{you();}} - プログラマの覚書 | ||||||||||||
|
投稿日時: 2007-01-27 08:18
そうなります。 現状、100% pure C#(てか IL?)なコードでは、低レベルフック以外のフックは出来ません。
そんなもんでしょうね。 他プロセスのメッセージをフックした時、フックプロシージャは他プロセスのコンテキストで動作するので、その状態で .NET ランタイムを呼び出すことは非常に危険な行為なのでしてはいけません(=単純に失敗する場合もあれば、最悪の場合、ターゲットプロセスをクラッシュさせてしまします)し、プロセスが異なるわけですから、フック元のプロセスがロードしているアセンブリ内のメソッドを .NET ランタイムの力を使わずに呼び出すことも容易ではありません。 目的とする動作を得るためには、最低限、フック DLL は 100% pure レガシ DLL?として構成する必要があります。 で、フックしたメッセージをマネージコードで処理したいとすると、フック DLL が捕捉したメッセージの情報を、非 .NET 的な、なんらかのプロセス間通信手段によってマネージコードに転送しなければなりません。(しかも、メッセージ置換が目的なら同期的に) ここの信頼性や保守性をキープするのはかなり面倒なので、腕の見せ所です (^^;;; [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2007-01-27 08:22 ] | ||||||||||||
