Usando a API de Contexto de Ativação
Os aplicativos podem gerenciar um contexto de ativação chamando diretamente as funções de contexto de ativação. Contextos de ativação são estruturas de dados na memória. O sistema pode usar as informações no contexto de ativação para redirecionar um aplicativo para carregar uma versão de DLL específica, uma instância de objeto COM ou uma versão de janela personalizada. Para obter mais informações, consulte Referência de contexto de ativação.
A API (interface de programação do aplicativo) pode ser usada para gerenciar o contexto de ativação e criar objetos nomeados por versão com manifestos. Os dois cenários a seguir ilustram como um aplicativo pode gerenciar um contexto de ativação chamando diretamente as funções de contexto de ativação. Na maioria dos casos, no entanto, o contexto de ativação é gerenciado pelo sistema. Os desenvolvedores de aplicativos e os provedores de assembly normalmente não precisam fazer chamadas para a pilha para gerenciar o contexto de ativação.
Processos e aplicativos que implementam camadas de indireção ou expedição.
Por exemplo, um usuário que gerencia contextos de ativação no loop de eventos. Sempre que a janela é acessada, como movendo o mouse sobre a janela, ActivateActCtx é chamado, o que ativa o contexto de ativação atual para o recurso, conforme mostrado no fragmento de código a seguir.
HANDLE hActCtx;
CreateWindow();
...
GetCurrentActCtx(&ActCtx);
...
ReleaseActCtx(&ActCtx);
No fragmento de código a seguir, a função de API ativa os contextos de ativação apropriados antes de chamar CallWindowProc. Quando CallWindowProc é chamado, ele usa esse contexto para passar uma mensagem para o Windows. Quando todas as operações de recurso forem concluídas, a função desativará o contexto.
ULONG_PTR ulpCookie;
HANDLE hActCtx;
if(ActivateActCtx(hActCtx, &ulpCookie))
{
...
CallWindowProc(...);
...
DeactivateActCtx(0, ulpCookie);
}
Camada de expedição do delegador.
Esse cenário se aplica a gerentes que gerenciam várias entidades com uma camada de API comum, como um gerenciador de driver. Embora ainda não tenha sido implementado, um exemplo disso seria o driver ODBC.
Nesse cenário, a camada intermediária se torna capaz de processar associações de assembly. Para obter o driver de associação específico da versão, os editores devem fornecer um manifesto e especificar dependências em componentes específicos nesse manifesto. O aplicativo base não se associa dinamicamente aos componentes; em tempo de execução, o gerenciador de driver gerencia as chamadas. Quando o driver ODBC é chamado com base na cadeia de conexão, ele carrega o driver apropriado. Em seguida, ele cria o contexto de ativação usando as informações no arquivo de manifesto do assembly.
Sem o manifesto, a ação padrão para o driver é usar o mesmo contexto especificado pelo aplicativo, neste exemplo, a versão 2 do MSVCRT. Como um manifesto existe, um contexto de ativação separado é estabelecido. Quando o driver ODBC é executado, ele se associa à versão 1 do assembly MSVCRT.
Sempre que o gerenciador de driver chama a camada de expedição, por exemplo, para obter o próximo conjunto de dados, ele usa os assemblies apropriados com base no contexto de ativação. O fragmento de código a seguir ilustra isso.
HANDLE hActCtx;
ULONG_PTR ulpCookie;
ACTCTX ActCtxToCreate = {...};
hActCtx = CreateActCtx(&ActCtxToCreate);
...;
if (ActivateActCtx(hActCtx, &ulpCookie))
{
...
ConnectDb(...);
DeactivateActCtx(0, ulpCookie);
}
...
ReleaseActCtx(hActCtx);