コードが共有DLLまたはexeで実行されているかどうかをプログラムで検出する方法
-
06-07-2019 - |
質問
Aには、グローバルホットキーの処理を簡素化するC#クラスがあります。
このクラスは、Win32-API関数 RegisterHotKey()
を使用してホットキーを登録します。
MSDNによると、この関数は0x0000から0xBFFFの範囲のID値を必要とします
アプリケーションからの呼び出し、および0xC000〜0xFFFFの範囲のID値
共有DLLから呼び出します。 GlobalAddAtom()
を使用して、実行中のIDを取得できます。
DLL内。
クラスのユーザーからこの区別を隠すには、クラス自体がどちらを決定する必要があります ホットキーを登録するときにID範囲が使用されます。さて、これを行うには、クラスは コードがアプリケーション内で実行されているか、アプリケーション内で実行されているかを検出できる 共有DLL。
しかし、これを行う方法は?これを行うための最良のC#/。NETの方法は何ですか?
解決
これを試してください:
bool isDll = this.GetType().Assembly.EntryPoint == null;
MSDN:
" Property Value MethodInfoオブジェクト のエントリポイントを表します このアセンブリ。エントリポイントがない場合 見つかった(たとえば、アセンブリは DLL)、null参照(Nothing in Visual Basic)が返されます。 "
他のヒント
それはあなたのクラスです-どこに置くかは知っています。
共有していない場合は、0xBFFF未満のIDを選択して完了です。
クラスが複数のアプリケーションで共有できるDLLに属している場合...または、制御していないコードで単純に共有できるため、IDを整理できない場合は、 GlobalAddAtom()
でIDを取得します(覚えておいてください) GlobalDeleteAtom()
を呼び出した後ホットキーの登録解除)。
説明
おそらく2つの異なるID範囲がある理由と、APIドキュメントが GlobalAddAtom()
を使用して共有DLLの後者の範囲のIDを取得することを推奨する理由について考えるのはおそらく時間をかける価値があります。 RegisterHotKey()
:
id
    [入力]ホットキーの識別子を指定します。 hWndパラメータがNULLの場合、ホットキーは特定のウィンドウではなく現在のスレッドに関連付けられます。同じhWndおよびidパラメーターを持つホットキーが既に存在する場合は、実行されたアクションの備考を参照してください。
このことから、ホットキーは、スレッドまたはウィンドウハンドル、および任意の16ビット数という情報の2つの潜在的なペアのいずれかによって一意に識別されると推測できます。ウィンドウハンドル( HWND
)を指定した場合、メッセージがそのウィンドウに送信されます。それ以外の場合は、スレッドに送信されます。
そう...特定のウィンドウに 1つのホットキーのみを登録する場合、IDは実際には重要ではありません 1 。他の誰もそのウィンドウのホットキーを登録できず、他のウィンドウのホットキーイベントはそれらのウィンドウにポストされます。同様に、特定のスレッドにウィンドウレスホットキーを1つだけ登録すると、そのホットキーのメッセージのみが表示されます。 アプリケーションのすべてのコードを制御する場合、ホットキーに必要なIDを選択できます。 あなたはそれらを踏むことができる ことができるすべてのコードを所有しているからです!
しかし、他のコードで呼び出すことができる汎用ルーチンを書いている場合はどうでしょうか?呼び出し側は既にそのIDを使用している可能性があり、同じウィンドウまたはスレッドも使用している場合、ホットキーを再定義するため、定数IDを確実に選択することはできません。または、(あなたの場合のように)実行時までに登録されるホットキーの数がわからない場合はどうなりますか?
実行時に選択するIDが他の誰も使用していないIDになるようにする方法が必要です。これが GlobalAddAtom()
の出番です。それに文字列を渡すと、その文字列に対応することが保証されたIDが与えられ、他のIDは与えられません。他の誰かが同じ文字列を渡さない限り、これはシステムにとって事実上一意です。おそらく、一意の文字列を思いつくことができます。会社名、または社会保障番号、および必要な新しいアトムごとに増分するプレフィックスを使用するだけです。または、あなたが本当に妄想している場合は、GUIDを使用します。
真実の背後にある真実
これで邪魔にならないように、少し混乱させてみましょう。Windowsは、 RegisterHotKey()
を呼び出すコードがDLLにあるかどうかを実際に気にしません。それはできません。次のルーチンを検討してください。
void RegisterSuperHappyFunHotKey(HWND hWnd, int id,
unsigned int fsModifiers, unsigned int vk)
{
RegisterHotKey(hWnd, id, fsModifiers, vk);
}
このルーチンは何もしませんが、そのパラメーターをWinAPI関数に転送します。
フィリップの回答の完了:
関数を呼び出しているアセンブリの参照を取得する必要があるため、コードは次のようになります。
Assembly assembly = Assembly.GetCallingAssembly();
Boolean isDll = assembly.EntryPoint == null;
これがお役に立てば幸いです。
リカルドラセルダカステロブランコ