複数のプログラムで、CLSID_XXXXX という COMオブジェクトを生成しています。
その、CLSID_XXXXX がどこかのプログラムで現在使われているか? または、
どのくらい生成されているか を調べることはできるのでしょうか?
CLSID_XXXXX のプログラム内で、共用変数を使ってカウントしていくような
方法しかないのでしょうか?
Running Object Table(ROT)というものがあります。
実行中のオブジェクトをROTに登録しておけば、
他のプログラムから登録したオブジェクトを参照
することができます。
IRunningObjectTableインターフェイス
GetRunningObjectTable関数
等を調べてみてください。
ありがとうございます。
調べてみます。
あくまで
> 実行中のオブジェクトをROTに登録しておけば、
の話です。
ROT に登録されていないオブジェクトがあるかどうかは調べられません。
お世話になっております。
IRunningObjectTable->Register() を COMオブジェクトの
FinalConstruct で設定して、
IRunningObjectTable->Revoke() を 同じCOMオブジェクトの
FinalRelease に 記述したのですが、
COMが開放されるタイミングにもかかわらず、 FinalRelease が呼ばれなくなってし
まいました。
Revoke() を COMのメソッド終了後に呼ぶようにしたときは、FinalRelease
が呼ばれるようになります
ROT関連について詳しく載っているサイトやサンプルなど
どこかにありませんでしょうか?
ROT がオブジェクトに対する参照を持っている限り、FinalRelease は呼ばれない(参照
カウントが 0 にならない)のではないでしょうか。
そもそも、ROT ってこういう目的のために使うものじゃない気がする。
MSDN にもモニカが云々って書いてあるし。
そもそも、どうしてプロセス境界を越えたインスタンス数の把握なんてしたいんですか?
>>どうしてプロセス境界を越えたインスタンス数の把握なんてしたいんですか?
以下のことができたらなと思ってます。
1.どこかで、COMオブジェクトが生成されていたら、
「現在、COMオブジェクトが使わているので、 しばらくお待ちください。」
みたいなメッセージを表示、 または、そのCOMオブジェクトを使っている
プロセスを教えてあげたいです。
2.使われているCOMオブジェクトに対して、 通知命令を出したりしたい
他プロセスの中にある、自分が生成したわけでもない COM オブジェクトの参照を取得し
て、いろいろやりたいってことですか?
うーん…であれば、ROT の出番かもしれませんね。
あわせて、モニカ(IMoniker)についても調べてみるといいと思います。
モニカってのは、COM オブジェクトに名前を付けたり、名前からオブジェクトを検索し
たりする機構のことです。
同じ名前を持つオブジェクトが既にあれば、そのインスタンスを取得するようなことも
可能なはずです。
COMオブジェクトとは別に、ROT登録用のオブジェクトを用意して、
・COMオブジェクト作成時に、ROT用のオブジェクトをROTに登録。
ROT用オブジェクトはCOMオブジェクトを弱参照(AddRefしない参照)する。
・COMオブジェクトのFinalReleaseのタイミングで、ROT用オブジェクトを
ROTから登録削除する。
・アプリケーションは、ROTを通じてROT用オブジェクトを取得し、
情報を問い合わせたり、通知を行ったりできる。
もしくは、ROT用オブジェクトがIServiceProviderインターフェイスを
実装し、IServiceProvider経由でCOMオブジェクトのインターフェイスが
取得できるようにする。
こんな感じで実現できそう。
Atata!!です。
CLSIDでコンポーネントを識別するなら以下のAPIが使用可能かどうかを検討した方が良い
かと思います。
・RegisterActiveObject
・RevokeActiveObject
・GetActiveObject
# これらは内部ではROTを使っているため、やることは変わらんかと
使用可能かどうかの判断は
・複数のコンポーネントを識別しなければならないかどうか?(RegisterActiveObjectは
確か後勝ち)
・サービスプロセスとサービスではないプロセス間で通信するかどうか?(簡単には出来
なかった気がします)
と言ったところでしょうか。
ただ、この要件
> 1.どこかで、COMオブジェクトが生成されていたら、
だけ満たせば済むのであれば、COM+アプリケーションとして構成して
COM+カタログで起動中かどうかを調べるだけで済むかと思います。
で、この要件
> 2.使われているCOMオブジェクトに対して、 通知命令を出したりしたい
も満たさなければならないならば、DLLサロゲートも含めて
アウトプロセスコンポーネントを検討した方が面倒がなくて良いかと。
# 自身でサロゲートプロセスを作成すれば、DLLのままでもいろいろ出来ますし。
最後にインプロセスかつROTを採用せざるを得ないのであれば、
Kerryさんが提示されている実装方法が良いと私も思います。
RegisterActiveObjectを使用する場合でも、この実装方法は有効です。
まぁ、CoDisconnectObjectとかIExternalConnectionとかも必要になるでしょうが。
# IServiceProviderは好みの分かれるところでしょうね。