IRunningObjectTable
COM公式ドキュメント
実行中オブジェクト テーブル(ROT: running object table)へのアクセスを管理します。ROT は各ワークステーション上でグローバルにアクセス可能な参照テーブルです。
解説(Remarks)
ROT には次の形式のエントリが格納されます: (pmkObjectName, pUnkObject)。
pmkObjectName 要素は、実行中オブジェクトを識別するモニカーへのポインターです。pUnkObject 要素は、実行中オブジェクト自体へのポインターです。バインド処理の間、モニカーは ROT 内の pmkObjectName エントリを参照し、オブジェクトが既に実行中かどうかを確認します。
モニカーによって名前付けできるオブジェクトは、読み込まれた時点で ROT に登録する必要があり、実行中でなくなった時点でその登録を取り消す必要があります。
メソッド 7
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
オブジェクトとそれを識別するモニカーを実行中オブジェクト テーブル(ROT)に登録します。
| grfFlags | ROT_FLAGS | in | ROT による punkObject への参照が弱参照か強参照かを指定し、ROT 内のエントリを通じたオブジェクトへのアクセスを制御します。詳細については「解説」セクションを参照してください。
| ||||||
| punkObject | IUnknown* | in | 実行中として登録されるオブジェクトへのポインター。 | ||||||
| pmkObjectName | IMoniker* | in | punkObject を識別するモニカーへのポインター。 | ||||||
| pdwRegister | DWORD* | out | この ROT エントリの識別子。後続の IRunningObjectTable::Revoke または IRunningObjectTable::NoteChangeTime の呼び出しで使用できます。呼び出し側はこのパラメーターに NULL を指定できません。エラーが発生した場合、*pdwRegister は 0 に設定されます。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG および E_OUTOFMEMORY のほか、次の値を返すことがあります。
| Return code | Description |
|---|---|
| メソッドが正常に完了しました。 | |
| モニカーとオブジェクトのペアは正常に登録されましたが、同じモニカーで別のオブジェクト(同一のオブジェクトである可能性もあります)が既に登録されています。 |
解説(Remarks)
このメソッドは、オブジェクトを識別するモニカーのもとに、そのオブジェクトへのポインターを登録します。IRunningObjectTable::GetObject でテーブルを検索する際、このモニカーがキーとして使用されます。
オブジェクトが登録されると、ROT は常にそのオブジェクトに対して AddRef を呼び出します。弱登録(ROTFLAGS_REGISTRATIONKEEPSALIVE が未設定)の場合、ROT はそのオブジェクトへの最後の強参照が解放された時点でオブジェクトを解放します。強登録(ROTFLAGS_REGISTRATIONKEEPSALIVE が設定)の場合、ROT はオブジェクトの登録が明示的に取り消されるまで、オブジェクトが破棄されないようにします。
LocalService または RunAs として登録されたサーバーは、Register の呼び出しで ROTFLAGS_ALLOWANYCLIENT フラグを設定することで、任意のクライアントからの接続を許可できます。このビットを設定するサーバーは、レジストリの AppID セクションに、その実行可能ファイルの AppID を参照する実行可能ファイル名を持っている必要があります。「アクティベーターとしてアクティブ化する(activate as activator)」サーバー(LocalService または RunAs として登録されていないサーバー)は、Register の呼び出しでこのフラグを設定してはなりません。サービスのインストールの詳細については、「Installing as a Service Application」を参照してください。
同じモニカーで 2 つ目のオブジェクトを登録した場合、または同じオブジェクトを同じモニカーで再登録した場合、ROT に 2 つ目のエントリが作成されます。この場合、Register は MK_S_MONIKERALREADYREGISTERED を返します。重複するエントリも異なる pdwRegister 識別子を持つため、Register の各呼び出しは IRunningObjectTable::Revoke の呼び出しと対にする必要があります。重複登録の問題点は、後続の IRunningObjectTable::IsRunning の呼び出しでモニカーを指定した場合に、どのオブジェクトが返されるかを判別する方法がないことです。
呼び出し側への注意
モニカー プロバイダー(自身のオブジェクトを識別するモニカーを配布し、他者からアクセスできるようにする側)である場合は、オブジェクトが実行を開始したときに Register メソッドを呼び出してオブジェクトを登録する必要があります。また、オブジェクトが読み込まれている間に名前を変更した場合にも、このメソッドを呼び出す必要があります。最も一般的なモニカー プロバイダーは、複合ドキュメントのリンク ソースです。これには、自身のドキュメント(またはドキュメントの一部分)へのリンクをサポートするサーバー アプリケーションや、自身のドキュメント内の埋め込みへのリンクをサポートするコンテナー アプリケーションが含まれます。リンクをサポートしないサーバー アプリケーションも、埋め込みへのリンクをサポートするコンテナー アプリケーションと連携するために ROT を利用できます。
サーバー アプリケーションを作成する場合は、オブジェクトが実行を開始したときに、通常は IOleObject::DoVerb の実装内で、そのオブジェクトを ROT に登録する必要があります。オブジェクトは完全なモニカーのもとに登録する必要があり、そのためには IOleClientSite::GetMoniker を使用してコンテナー ドキュメントのモニカーを取得する必要があります。また、コンテナー ドキュメントの名前が変更されたときに呼び出される IOleObject::SetMoniker の実装内でも、オブジェクトの登録を取り消して再登録する必要があります。
埋め込みへのリンクをサポートするコンテナー アプリケーションを作成する場合は、ドキュメントが読み込まれたときにそのドキュメントを ROT に登録する必要があります。ドキュメントの名前が変更された場合は、ROT で登録を取り消して再登録し、ドキュメント内の各埋め込みオブジェクトが自身を再登録できるよう、それらに対して IOleObject::SetMoniker を呼び出す必要があります。
ROT に登録されたオブジェクトは、実行中でなくなったとき、またはそのモニカーが変更されたときに、明示的に登録を取り消す必要があります。ROT からエントリを自動的に削除する方法がシステムには存在しないため、この登録の取り消しは重要です。pdwRegister を通じて書き込まれた識別子をキャッシュしておき、それを IRunningObjectTable::Revoke の呼び出しで使用して登録を取り消す必要があります。強登録の場合、オブジェクトの登録が取り消されると強参照が解放されます。
Windows Server 2003 以降では、予期しないサーバーの問題により古いエントリが ROT に残った場合、COM がそれらの古いエントリを ROT から自動的に削除します。
システムによる Register の実装では、pmkObjectName パラメーターに対して IMoniker::Reduce を呼び出し、登録前にモニカーが完全に簡約(reduce)されていることを保証します。オブジェクトが複数の完全に簡約されたモニカーで識別される場合は、それらすべてのモニカーのもとに登録する必要があります。
IRunningObjectTable::Register の呼び出しで以前に登録されたエントリを、実行中オブジェクト テーブル(ROT)から削除します。
| dwRegister | DWORD | in | 取り消す ROT エントリの識別子。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG および S_OK を返すことがあります。
解説(Remarks)
このメソッドは IRunningObjectTable::Register の呼び出しの効果を取り消し、モニカーと、そのモニカーで識別されるオブジェクトへのポインターの両方を削除します。
呼び出し側への注意
モニカー プロバイダー(自身のオブジェクトを識別するモニカーを配布し、他者からアクセスできるようにする側)は、実行を停止するときに Revoke メソッドを呼び出して、自身のオブジェクトの登録を取り消す必要があります。あらかじめ IRunningObjectTable::Register を呼び出し、そのメソッドが返した識別子を保存しておく必要があります。Revoke の呼び出し時にはその識別子を使用します。最も一般的なモニカー プロバイダーは、複合ドキュメントのリンク ソースです。これには、自身のドキュメント(またはドキュメントの一部分)へのリンクをサポートするサーバー アプリケーションや、自身のドキュメント内の埋め込みへのリンクをサポートするコンテナー アプリケーションが含まれます。リンクをサポートしないサーバー アプリケーションも、埋め込みへのリンクをサポートするコンテナー アプリケーションと連携するために ROT を利用できます。
コンテナー アプリケーションを作成する場合は、ドキュメントが閉じられたときにそのドキュメントの登録を取り消す必要があります。また、ドキュメントの名前が変更されたときには、再登録する前にそのドキュメントの登録を取り消す必要があります。
サーバー アプリケーションを作成する場合は、オブジェクトが閉じられたときにそのオブジェクトの登録を取り消す必要があります。また、コンテナー ドキュメントの名前が変更されたときには、再登録する前にオブジェクトの登録を取り消す必要があります(IOleObject::SetMoniker を参照)。
指定されたモニカーで識別されるオブジェクトが現在実行中かどうかを判別します。
| pmkObjectName | IMoniker* | in | モニカー上の IMoniker インターフェイスへのポインター。 |
戻り値
オブジェクトが実行中の状態にある場合、戻り値は TRUE です。それ以外の場合は FALSE です。
解説(Remarks)
このメソッドは、オブジェクトが実行中かどうかを示すだけです。実行中オブジェクトへのポインターを取得するには、IRunningObjectTable::GetObject メソッドを使用してください。
呼び出し側への注意
通常、IsRunning メソッドを呼び出すのは、独自のモニカー クラスを作成している(すなわち IMoniker インターフェイスを実装している)場合のみです。通常、このメソッドは IMoniker::IsRunning の実装内から呼び出します。ただし、これを行うのは IMoniker::IsRunning の pmkToLeft パラメーターが NULL の場合に限ります。それ以外の場合は、代わりに pmkToLeft パラメーターに対して IMoniker::IsRunning を呼び出す必要があります。指定されたモニカーで識別されるオブジェクトが実行中かどうかを判別し、実行中の場合はそのオブジェクトへのポインターを取得します。
| pmkObjectName | IMoniker* | in | モニカー上の IMoniker インターフェイスへのポインター。 |
| ppunkObject | IUnknown** | out | 実行中オブジェクトへのインターフェイス ポインターを受け取る IUnknown ポインター変数へのポインター。成功した場合、実装はそのオブジェクトに対して AddRef を呼び出します。Release を呼び出すのは呼び出し側の責任です。オブジェクトが実行中でない場合、またはエラーが発生した場合、実装は *ppunkObject を NULL に設定します。 |
戻り値
このメソッドは、次の値を返すことがあります。
| Return code | Description |
|---|---|
| pmkObjectName が ROT 内で見つかり、ポインターが取得されたことを示します。 | |
| ROT 内に pmkObjectName のエントリが存在しないか、それが識別するオブジェクトが既に実行中でない(この場合、エントリは取り消されます)ことを示します。 |
解説(Remarks)
このメソッドは、pmkObjectName で指定されたモニカーを ROT で確認します。そのモニカーが以前に IRunningObjectTable::Register の呼び出しで登録されていた場合、このメソッドはその時点で登録されたポインターを返します。
呼び出し側への注意
通常、IRunningObjectTable::GetObject メソッドを呼び出すのは、独自のモニカー クラスを作成している(すなわち IMoniker インターフェイスを実装している)場合のみです。通常、このメソッドは IMoniker::BindToObject の実装内から呼び出します。ただし、すべての IMoniker::BindToObject の実装がこのメソッドを呼び出す必要があるわけではないことに注意してください。モニカーにプレフィックス(IMoniker::BindToObject の pmkToLeft パラメーターが非 NULL であることで示される)が付くことが想定される場合は、ROT を確認すべきではありません。その理由は、ROT に登録されるのは完全なモニカーのみであり、モニカーにプレフィックスがある場合、そのモニカーはコンポジットの一部であって完全ではないためです。代わりに、モニカーはプレフィックスで識別されるオブジェクト(たとえば、自身のモニカーで識別されるオブジェクトのコンテナー)にサービスを要求すべきです。
実行中オブジェクトが最後に変更された時刻を記録します。そのオブジェクトは、あらかじめ実行中オブジェクト テーブル(ROT)に登録されている必要があります。このメソッドは、最終変更時刻を ROT に格納します。
| dwRegister | DWORD | in | 変更されたオブジェクトの ROT エントリの識別子。この値は、以前に IRunningObjectTable::Register によって返されたものです。 |
| pfiletime | FILETIME* | in | オブジェクトの最終変更時刻を格納した FILETIME 構造体へのポインター。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG および S_OK を返すことがあります。
解説(Remarks)
このメソッドで記録された時刻は、IRunningObjectTable::GetTimeOfLastChange を呼び出すことで取得できます。
呼び出し側への注意
モニカー プロバイダー(自身のオブジェクトを識別するモニカーを配布し、他者からアクセスできるようにする側)は、自身のオブジェクトが変更されるたびに NoteChangeTime メソッドを呼び出す必要があります。あらかじめ IRunningObjectTable::Register を呼び出し、そのメソッドが返した識別子を保存しておく必要があります。NoteChangeTime の呼び出し時にはその識別子を使用します。最も一般的なモニカー プロバイダーは、複合ドキュメントのリンク ソースです。これには、自身のドキュメント(またはドキュメントの一部分)へのリンクをサポートするサーバー アプリケーションや、自身のドキュメント内の埋め込みへのリンクをサポートするコンテナー アプリケーションが含まれます。リンクをサポートしないサーバー アプリケーションも、埋め込みへのリンクをサポートするコンテナー アプリケーションと連携するために ROT を利用できます。
オブジェクトが最初に ROT に登録されると、ROT はその最終変更時刻として、登録されるモニカーに対して IMoniker::GetTimeOfLastChange を呼び出して返された値を記録します。
オブジェクトが最後に変更された時刻を取得します。
| pmkObjectName | IMoniker* | in | モニカー上の IMoniker インターフェイスへのポインター。 |
| pfiletime | FILETIME* | out | オブジェクトの最終変更時刻を受け取る FILETIME 構造体へのポインター。 |
戻り値
このメソッドは、次の値を返すことがあります。
| Return code | Description |
|---|---|
| メソッドが正常に完了しました。 | |
| ROT 内に pmkObjectName のエントリが存在しないか、それが識別するオブジェクトが既に実行中でない(この場合、エントリは取り消されます)ことを示します。 |
解説(Remarks)
このメソッドは、IRunningObjectTable::NoteChangeTime の呼び出しによってこのオブジェクトについて最後に報告された変更時刻を返します。NoteChangeTime がそれまでに呼び出されていない場合、このメソッドはオブジェクトが登録されたときに記録された時刻を返します。
このメソッドは、2 つのオブジェクト間の接続(一方のオブジェクトが他方を識別するモニカーを保持している状態で表される)が最新であるかどうかを確認できるようにするために用意されています。たとえば、一方のオブジェクトが他方のオブジェクトに関するキャッシュ情報を保持している場合、このメソッドを使用して、キャッシュが最後に更新されて以降にオブジェクトが変更されたかどうかを確認できます。IMoniker::GetTimeOfLastChange を参照してください。
呼び出し側への注意
通常、GetTimeOfLastChange を呼び出すのは、独自のモニカー クラスを作成している(すなわち IMoniker インターフェイスを実装している)場合のみです。通常、このメソッドは IMoniker::GetTimeOfLastChange の実装内から呼び出します。ただし、これを行うのは IMoniker::GetTimeOfLastChange の pmkToLeft パラメーターが NULL の場合に限ります。それ以外の場合は、代わりに pmkToLeft パラメーターに対して IMoniker::GetTimeOfLastChange を呼び出す必要があります。実行中オブジェクト テーブル(ROT)に現在登録されているすべてのオブジェクトのモニカーを列挙できる列挙子を作成し、それへのポインターを返します。
| ppenumMoniker | IEnumMoniker** | out | ROT 用の新しい列挙子へのインターフェイス ポインターを受け取る IEnumMoniker ポインター変数へのポインター。成功した場合、実装はその列挙子に対して AddRef を呼び出します。Release を呼び出すのは呼び出し側の責任です。エラーが発生した場合、実装は *ppenumMoniker を NULL に設定します。 |
戻り値
このメソッドは、標準の戻り値 E_OUTOFMEMORY および S_OK を返すことがあります。
解説(Remarks)
IRunningObjectTable::EnumRunning は、列挙子オブジェクト上の IEnumMoniker インターフェイスを作成し、それへのポインターを返す必要があります。その後、標準の列挙子メソッドを呼び出して、レジストリに現在登録されているモニカーを列挙できます。列挙子の作成後に ROT に登録されたモニカーを列挙するために、この列挙子を使用することはできません。
EnumRunning メソッドは、主にシステムがアラート オブジェクト テーブルを実装する際に使用することを目的としています。なお、OLE 2 にはアラート オブジェクト テーブルの実装は含まれていません。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IRunningObjectTable "{00000010-0000-0000-C000-000000000046}" #usecom global IRunningObjectTable IID_IRunningObjectTable "{}" #comfunc global IRunningObjectTable_Register 3 int,sptr,sptr,var #comfunc global IRunningObjectTable_Revoke 4 int #comfunc global IRunningObjectTable_IsRunning 5 sptr #comfunc global IRunningObjectTable_GetObject 6 sptr,sptr #comfunc global IRunningObjectTable_NoteChangeTime 7 int,var #comfunc global IRunningObjectTable_GetTimeOfLastChange 8 sptr,var #comfunc global IRunningObjectTable_EnumRunning 9 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IRunningObjectTable "{00000010-0000-0000-C000-000000000046}" #usecom global IRunningObjectTable IID_IRunningObjectTable "{}" #comfunc global IRunningObjectTable_Register 3 int,sptr,sptr,sptr #comfunc global IRunningObjectTable_Revoke 4 int #comfunc global IRunningObjectTable_IsRunning 5 sptr #comfunc global IRunningObjectTable_GetObject 6 sptr,sptr #comfunc global IRunningObjectTable_NoteChangeTime 7 int,sptr #comfunc global IRunningObjectTable_GetTimeOfLastChange 8 sptr,sptr #comfunc global IRunningObjectTable_EnumRunning 9 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。