Utilisation de l’API de contexte d’activation
Les applications peuvent gérer un contexte d’activation en appelant directement les fonctions de contexte d’activation. Les contextes d’activation sont des structures de données en mémoire. Le système peut utiliser les informations dans le contexte d’activation pour rediriger une application afin de charger une version de DLL particulière, un instance d’objet COM ou une version de fenêtre personnalisée. Pour plus d’informations, consultez Informations de référence sur le contexte d’activation.
L’interface de programmation d’application (API) peut être utilisée pour gérer le contexte d’activation et créer des objets nommés par une version avec des manifestes. Les deux scénarios suivants illustrent comment une application peut gérer un contexte d’activation en appelant directement les fonctions de contexte d’activation. Toutefois, dans la plupart des cas, le contexte d’activation est géré par le système. Les développeurs d’applications et les fournisseurs d’assemblys n’ont généralement pas besoin d’appeler la pile pour gérer le contexte d’activation.
Processus et applications qui implémentent des couches d’indirection ou de répartition.
Par exemple, un utilisateur qui gère les contextes d’activation dans la boucle d’événement. Chaque fois que la fenêtre est accessible, par exemple en déplaçant la souris sur la fenêtre, ActivateActCtx est appelé, ce qui active le contexte d’activation actuel pour la ressource, comme illustré dans le fragment de code suivant.
HANDLE hActCtx;
CreateWindow();
...
GetCurrentActCtx(&ActCtx);
...
ReleaseActCtx(&ActCtx);
Dans le fragment de code suivant, la fonction API active les contextes d’activation appropriés avant d’appeler CallWindowProc. Lorsque CallWindowProc est appelé, il utilise ce contexte pour passer un message à Windows. Une fois toutes les opérations de ressources terminées, la fonction désactive le contexte.
ULONG_PTR ulpCookie;
HANDLE hActCtx;
if(ActivateActCtx(hActCtx, &ulpCookie))
{
...
CallWindowProc(...);
...
DeactivateActCtx(0, ulpCookie);
}
Couche de répartition de délégant.
Ce scénario s’applique aux gestionnaires qui gèrent plusieurs entités avec une couche API commune, telle qu’un gestionnaire de pilotes. Bien qu’il n’ait pas encore été implémenté, le pilote ODBC en est un exemple.
Dans ce scénario, la couche centrale devient capable de traiter les liaisons d’assembly. Pour obtenir le pilote de liaison spécifique à la version, les éditeurs doivent fournir un manifeste et spécifier des dépendances sur des composants spécifiques dans ce manifeste. L’application de base ne se lie pas dynamiquement aux composants ; au moment de l’exécution, le gestionnaire de pilotes gère les appels. Lorsque le pilote ODBC est appelé en fonction de la chaîne de connexion, il charge le pilote approprié. Il crée ensuite le contexte d’activation à l’aide des informations contenues dans le fichier manifeste d’assembly.
Sans le manifeste, l’action par défaut du pilote consiste à utiliser le même contexte que celui spécifié par l’application (dans cet exemple, version 2 de MSVCRT). Étant donné qu’un manifeste existe, un contexte d’activation distinct est établi. Lorsque le pilote ODBC s’exécute, il est lié à la version 1 de l’assembly MSVCRT.
Chaque fois que le gestionnaire de pilotes appelle la couche de répartition (par exemple, pour obtenir le jeu de données suivant), il utilise les assemblys appropriés en fonction du contexte d’activation. Le fragment de code suivant illustre cela.
HANDLE hActCtx;
ULONG_PTR ulpCookie;
ACTCTX ActCtxToCreate = {...};
hActCtx = CreateActCtx(&ActCtxToCreate);
...;
if (ActivateActCtx(hActCtx, &ulpCookie))
{
...
ConnectDb(...);
DeactivateActCtx(0, ulpCookie);
}
...
ReleaseActCtx(hActCtx);