アクティブ化コンテキスト API の使用
アプリケーションは、 アクティブ化コンテキスト 関数を直接呼び出すことによって、アクティブ化コンテキストを管理できます。 アクティブ化コンテキストは、メモリ内のデータ構造です。 システムは、アクティブ化コンテキストの情報を使用して、特定の DLL バージョン、COM オブジェクト インスタンス、またはカスタム ウィンドウ バージョンを読み込むようにアプリケーションをリダイレクトできます。 詳細については、「 アクティブ化コンテキスト リファレンス」を参照してください。
アプリケーション プログラミング インターフェイス (API) を使用して、アクティブ化コンテキストを管理し、 マニフェストを使用してバージョン名付きオブジェクトを作成できます。 次の 2 つのシナリオは、アプリケーションがアクティブ化コンテキスト関数を直接呼び出すことによってアクティブ化コンテキストを管理する方法を示しています。 ただし、ほとんどの場合、アクティブ化コンテキストはシステムによって管理されます。 アプリケーション開発者とアセンブリ プロバイダーは、通常、アクティブ化コンテキストを管理するためにスタックを呼び出す必要はありません。
間接参照またはディスパッチ レイヤーを実装するプロセスとアプリケーション。
たとえば、イベント ループでアクティブ化コンテキストを管理しているユーザーなどです。 ウィンドウの上にマウスを移動するなどして、ウィンドウにアクセスするたびに ActivateActCtx が呼び出され、次のコード フラグメントに示すように、リソースの現在のアクティブ化コンテキストがアクティブ化されます。
HANDLE hActCtx;
CreateWindow();
...
GetCurrentActCtx(&ActCtx);
...
ReleaseActCtx(&ActCtx);
次のコード フラグメントでは、API 関数は CallWindowProc を呼び出す前に、適切なアクティブ化コンテキストをアクティブ化します。 CallWindowProc が呼び出されると、このコンテキストを使用して Windows にメッセージが渡されます。 すべてのリソース操作が完了すると、関数はコンテキストを非アクティブ化します。
ULONG_PTR ulpCookie;
HANDLE hActCtx;
if(ActivateActCtx(hActCtx, &ulpCookie))
{
...
CallWindowProc(...);
...
DeactivateActCtx(0, ulpCookie);
}
委任者ディスパッチ レイヤー。
このシナリオは、ドライバー マネージャーなど、共通の API レイヤーを使用して複数のエンティティを管理するマネージャーに適用されます。 まだ実装されていませんが、この例としては ODBC ドライバーがあります。
このシナリオでは、中間層がアセンブリ バインドを処理できるようになります。 バージョン固有のバインディング ドライバーを取得するには、発行元がマニフェストを提供し、そのマニフェスト内の特定のコンポーネントへの依存関係を指定する必要があります。 基本アプリケーションは、コンポーネントに動的にバインドされません。実行時に、ドライバー マネージャーが呼び出しを管理します。 接続文字列に基づいて ODBC ドライバーが呼び出されると、適切なドライバーが読み込まれます。 次に、アセンブリ マニフェスト ファイル内の情報を使用してアクティブ化コンテキストを作成します。
マニフェストがない場合、ドライバーの既定のアクションは、アプリケーションで指定されたコンテキストと同じコンテキスト (この例ではバージョン 2 の MSVCRT) を使用することです。 マニフェストが存在するため、個別のアクティブ化コンテキストが確立されます。 ODBC ドライバーを実行すると、MSVCRT アセンブリのバージョン 1 にバインドされます。
ドライバー マネージャーは、ディスパッチ レイヤーを呼び出すたびに (たとえば、次のデータ セットを取得するために)、アクティブ化コンテキストに基づいて適切なアセンブリを使用します。 次のコード フラグメントは、これを示しています。
HANDLE hActCtx;
ULONG_PTR ulpCookie;
ACTCTX ActCtxToCreate = {...};
hActCtx = CreateActCtx(&ActCtxToCreate);
...;
if (ActivateActCtx(hActCtx, &ulpCookie))
{
...
ConnectDb(...);
DeactivateActCtx(0, ulpCookie);
}
...
ReleaseActCtx(hActCtx);