タイプ ライブラリに記述されているすべて[oleautomation]
のインターフェイス (およびすべての[dual]
インターフェイス) は、タイプ ライブラリ マーシャラーを使用できます。
ここでは、プロキシ スタブ DLL を見つける手間を、タイプ ライブラリを見つける手間と交換します。assembly
したがって、次のように、アセンブリのマニフェスト (要素の直下) でインターフェイスとタイプ ライブラリを宣言します。
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}" />
<!-- This also works for a type library embedded in a DLL -->
<file name="FooBar.tlb">
<!-- If you have multiple embedded type libraries, use the resourceid attribute -->
<typelib tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}"
version="1.0" />
</file>
インターフェイスがインターフェイスではなく[oleautomation]
、プロキシ スタブ DLL を分離したい場合は、次のようなものを使用します。
<file name="FooBarPS.dll">
<comInterfaceProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
AcomInterfaceProxyStub
は によく似ていますcomClass
が、プロキシ/スタブに重点を置いており、インターフェイスに関連付けられています。
分離されたプロキシ/スタブ DLL の有無にかかわらずテストする場合は、プロキシ/スタブセクションのコメントを (解除) することにより、(要素レベルcomInterfaceExternalProxyStub
の下で) と(要素の下で)のペアで同じ効果を実現できます。assembly
comClass
file
file
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}" />
<file name="FooBarPS.dll">
<comClass description="PSFactoryBuffer"
clsid="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
確かではありませんが、標準のプロキシ/スタブ DLL が複数のインターフェイスに使用されている場合は、このアプローチも使用する必要があります。
編集:これはあなたにとって新しいものではないようです。あなたの問題は、動的にロードされたライブラリのマニフェストをアクティブにしても、セッション サービスでは、その状態が現在のスレッドにのみ残ることです。そのため、COM ワーカー スレッド (RPC スレッドなど) は、インターフェイス、コクラス、およびプロキシ/スタブについて認識しません。
ブローカ サービス ( REGDB_E_IIDNOTREG
) に表示されるエラーは、セッション サービスからのマーシャリングが原因である可能性があります。メソッドが戻った後に発生するため、セッションサービスではそのエラーは発生しません。
ただし、当然のことながら、ブローカ サービスで発生している可能性があります。ライブラリはロードされず、ましてやマニフェストはロードされません。
私がお勧めするアプローチは、セッション サービスとブローカー サービスに、登録不要の COM 情報を宣言するアセンブリに依存するマニフェストを持たせることです。このように、すべてがデフォルトのアクティベーション コンテキストの一部となり、アクティベーション コンテキストに関して何もする必要はありません。
デフォルトのアクティベーション コンテキストに事前に必要なものを含める以外に、所有していないスレッドのアクティベーション コンテキストを制御することはできないことに注意してください。
あなたの質問のこの部分について:
複数のアプリケーションが同じモジュールを持っていてもバージョンが異なる可能性があるため、DLL のプロキシ/スタブを登録できません。したがって、登録不要のアクティベーションを使用します。
あなたが何を言おうとしているのか、私にははっきりしません。モジュールに下位互換性がある場合は、心配する必要はありません。そうでない場合は、別の CLSID/ProgID を使用してください。
COM に違反しているため、実際には異なるインターフェイスで同じ IID を使用しているという意味ではないことを願っています。この問題を解決する最善の方法は、やらないことです。もう 1 つの方法は、セッション サービスとブローカー サービスの両方で、専用のアクティベーション コンテキストを持つ専用のスレッドを使用することです。これは、おそらくセッション サービスだけで見てきたように、非常に脆弱なアプローチです。
私が見ているように、COM 分離はまったく必要ないかもしれません。ただし、それでも必要な場合は、ブローカーとセッションの両方のサービスに対して実行する必要があり、実行時ではなくマニフェストから実行する必要があります。