Compartilhar via


Execução lado a lado no .NET Framework

Observação

Este artigo é específico do .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

A execução lado a lado é a capacidade de executar várias versões de um aplicativo ou componente no mesmo computador. Você pode ter várias versões do common language runtime e várias versões de aplicativos e componentes que usam uma versão do runtime, no mesmo computador ao mesmo tempo.

A ilustração a seguir mostra vários aplicativos usando duas versões diferentes do runtime no mesmo computador. Os aplicativos A, B e C usam o runtime versão 1.0, enquanto o aplicativo D usa o runtime versão 1.1.

Execução lado a lado de diferentes versões de runtime,

O .NET Framework consiste no common language runtime e uma coleção de assemblies que contêm os tipos de API. Versões são atribuídas ao runtime e aos assemblies do .NET Framework separadamente. Por exemplo, a versão 4.0 do runtime é, na verdade, a versão 4.0.319, enquanto a versão 1.0 dos assemblies do .NET Framework é a versão 1.0.3300.0.

A ilustração a seguir mostra vários aplicativos usando duas versões diferentes de um componente no mesmo computador. O aplicativo A e B usam a versão 1.0 do componente, enquanto o Aplicativo C usa a versão 2.0 do mesmo componente.

Diagrama que mostra a execução lado a lado de um componente.

A execução lado a lado oferece mais controle sobre quais versões de um componente um aplicativo associa e mais controle sobre qual versão do runtime um aplicativo usa.

Benefícios da execução lado a lado

Antes do Windows XP e do .NET Framework, ocorreram conflitos de DLL porque os aplicativos não conseguiam distinguir entre versões incompatíveis do mesmo código. As informações de tipo contidas em uma DLL foram associadas apenas a um nome de arquivo. Um aplicativo não tinha como saber se os tipos contidos em uma DLL eram os mesmos tipos com os quais o aplicativo foi criado. Como resultado, uma nova versão de um componente pode substituir uma versão mais antiga e interromper aplicativos.

A execução lado a lado e o .NET Framework fornecem os seguintes recursos para eliminar conflitos de DLL:

  • Assemblies com nomes fortes.

    A execução lado a lado usa assemblies com nome forte para associar informações de tipo a uma versão específica de um assembly. Isso impede que um aplicativo ou componente se vincule a uma versão inválida de um assembly. Assemblies de nome forte também permitem que várias versões de um arquivo existam no mesmo computador e sejam usadas por aplicativos. Para obter mais informações, consulte Strong-Named Assemblies.

  • Armazenamento de código com reconhecimento de versão.

    O .NET Framework fornece armazenamento de código ciente de versão no cache de assembly global. O cache de assembly global é um cache de código amplo no computador presente em todos os computadores com o .NET Framework instalado. Ele armazena assemblies com base em informações de versão, cultura e editor e dá suporte a várias versões de componentes e aplicativos. Para obter mais informações, consulte o Cache de Assembly Global.

  • Isolamento.

    Usando o .NET Framework, você pode criar aplicativos e componentes que são executados isoladamente. O isolamento é um componente essencial da execução lado a lado. Envolve estar ciente dos recursos que você está usando e compartilhar recursos com confiança entre várias versões de um aplicativo ou componente. O isolamento também inclui o armazenamento de arquivos de uma maneira específica à versão. Para obter mais informações sobre isolamento, consulte Diretrizes para criar componentes para execução lado a lado.

Compatibilidade de versão

As versões 1.0 e 1.1 do .NET Framework foram projetadas para serem compatíveis entre si. Um aplicativo criado com o .NET Framework versão 1.0 deve ser executado na versão 1.1 e um aplicativo criado com o .NET Framework versão 1.1 deve ser executado na versão 1.0. No entanto, observe que os recursos de API adicionados na versão 1.1 do .NET Framework não funcionarão com a versão 1.0 do .NET Framework. Os aplicativos criados com a versão 2.0 serão executados somente na versão 2.0. Os aplicativos da versão 2.0 não serão executados na versão 1.1 ou anterior.

As versões do .NET Framework são tratadas como uma única unidade que consiste no runtime e seus assemblies do .NET Framework associados (um conceito conhecido como unificação de assemblies). Você pode redirecionar a associação de assembly para incluir outras versões dos assemblies do .NET Framework, mas substituir a associação padrão do assembly pode ser arriscado e deve ser rigorosamente testado antes da implantação.

Localizando informações de versão do runtime

Informações sobre qual versão de runtime um aplicativo ou componente foi compilado e com quais versões do runtime o aplicativo precisa executar são armazenadas em dois locais. Quando um aplicativo ou componente é compilado, as informações sobre a versão de runtime usada para compilá-lo são armazenadas no executável gerenciado. As informações sobre as versões de runtime necessárias pelo aplicativo ou componente são armazenadas no arquivo de configuração do aplicativo.

Informações da versão de runtime no executável gerenciado

O cabeçalho de arquivo PE (executável portátil) de cada aplicativo gerenciado e componente contém informações sobre a versão de runtime com a qual ele foi criado. O common language runtime usa essas informações para determinar a versão mais provável do runtime que o aplicativo precisa executar.

Informações de versão de runtime no arquivo de configuração do aplicativo

Além das informações no cabeçalho do arquivo PE, um aplicativo pode ser implantado com um arquivo de configuração de aplicativo que fornece informações de versão de runtime. O arquivo de configuração do aplicativo é um arquivo baseado em XML criado pelo desenvolvedor de aplicativos e que é fornecido com um aplicativo. O <requiredRuntime> elemento da <startup> seção, se ele estiver presente neste arquivo, especifica quais versões do runtime e quais versões de um componente o aplicativo dá suporte. Você também pode usar esse arquivo no teste para testar a compatibilidade de um aplicativo com diferentes versões do runtime.

O código não gerenciado, incluindo aplicativos COM e COM+, pode ter arquivos de configuração de aplicativo que o runtime usa para interagir com o código gerenciado. O arquivo de configuração do aplicativo afeta qualquer código gerenciado que você ativar por meio de COM. O arquivo pode especificar quais versões de runtime têm suporte, bem como redirecionamentos de assembly. Por padrão, os aplicativos de interoperabilidade COM que chamam o código gerenciado usam a versão mais recente do runtime instalado no computador.

Para obter mais informações sobre os arquivos de configuração do aplicativo, consulte Configurando aplicativos.

Determinando qual versão do runtime carregar

O common language runtime usa as seguintes informações para determinar qual versão do runtime carregar para um aplicativo:

  • As versões de runtime disponíveis.

  • As versões de runtime com suporte em um aplicativo.

Versões de runtime com suporte

O runtime usa o arquivo de configuração do aplicativo e o cabeçalho de arquivo PE (executável portátil) para determinar qual versão do runtime um aplicativo dá suporte. Se nenhum arquivo de configuração de aplicativo estiver presente, o runtime carregará a versão de runtime especificada no cabeçalho do arquivo PE do aplicativo, se essa versão estiver disponível.

Se um arquivo de configuração de aplicativo estiver presente, o runtime determinará a versão de runtime apropriada a ser carregada com base nos resultados do seguinte processo:

  1. O runtime examina o <supportedRuntime> elemento Element no arquivo de configuração do aplicativo. Se uma ou mais das versões de runtime com suporte especificadas no <supportedRuntime> elemento estiverem presentes, o runtime carregará a versão de runtime especificada pelo primeiro <supportedRuntime> elemento. Se essa versão não estiver disponível, o runtime examinará o próximo <supportedRuntime> elemento e tentará carregar a versão de runtime especificada. Se essa versão de runtime não estiver disponível, os elementos subsequentes <supportedRuntime> serão examinados. Se nenhuma das versões de runtime com suporte estiver disponível, o runtime não carregará uma versão de runtime e exibirá uma mensagem para o usuário (consulte a etapa 3).

  2. O runtime lê o cabeçalho do arquivo PE do arquivo executável do aplicativo. Se a versão de runtime especificada pelo cabeçalho do arquivo PE estiver disponível, o runtime carregará essa versão. Se a versão de runtime especificada não estiver disponível, o runtime procurará por uma versão de runtime determinada pela Microsoft como compatível com a versão de runtime no cabeçalho PE. Se essa versão não for encontrada, o processo continuará na etapa 3.

  3. O runtime exibe uma mensagem informando que a versão de runtime compatível com o aplicativo não está disponível. O runtime não está carregado.

    Observação

    Você pode suprimir a exibição dessa mensagem usando o valor NoGuiFromShim na chave do Registro HKLM\Software\Microsoft\. NETFramework ou usando a variável de ambiente COMPLUS_NoGuiFromShim. Por exemplo, você pode suprimir a mensagem para aplicativos que normalmente não interagem com o usuário, como instalações autônomas ou serviços windows. Quando essa exibição de mensagem é suprimida, o runtime grava uma mensagem no log de eventos. Defina o valor do Registro NoGuiFromShim como 1 para suprimir essa mensagem para todos os aplicativos em um computador. Como alternativa, defina a variável de ambiente COMPLUS_NoGuiFromShim como 1 para suprimir a mensagem para aplicativos em execução em um contexto de usuário específico.

Observação

Depois que uma versão de runtime é carregada, os redirecionamentos de associação de assembly pode especificar que uma versão diferente de um assembly do .NET Framework individual será carregada. Esses redirecionamentos de associação afetam apenas o componente específico que é redirecionado.

Nomes parcialmente qualificados e execução lado a lado do assembly

Como eles são uma fonte potencial de problemas de lado a lado, referências parcialmente qualificadas do assembly podem ser usadas apenas para associar aos assemblies dentro de um diretório de aplicativo. Evite usar referências de assembly parcialmente qualificadas no seu código.

Para atenuar referências de assembly parcialmente qualificadas no código, você pode usar o <elemento qualifyAssembly> em um arquivo de configuração de aplicativo para qualificar totalmente as referências de assembly parcialmente qualificadas que ocorrem no código. Use o <qualifyAssembly> elemento para especificar apenas os campos que não foram definidos na referência parcial. A identidade listada no atributo fullName deve conter todas as informações necessárias para a qualificação completa do nome do assembly: nome do assembly, chave pública, cultura e versão.

O exemplo a seguir mostra a entrada de arquivo de configuração de aplicativo para qualificar totalmente um assembly denominado myAssembly.

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="myAssembly"
fullName="myAssembly,
      version=1.0.0.0,
publicKeyToken=...,
      culture=neutral"/>
</assemblyBinding>

Sempre que um assembly carregar referências da instrução myAssembly, essas definições do arquivo de configuração fazem com que o runtime realize automaticamente a conversão da referência myAssembly parcialmente qualificada em uma referência totalmente qualificada. Por exemplo, Assembly.Load("myAssembly") torna-se Assembly.Load("myAssembly, version=1.0.0.0, publicKeyToken=..., culture=neutral").

Observação

Você pode usar o método LoadWithPartialName para ignorar a restrição do runtime de linguagem comum que proíbe que assemblies parcialmente referenciados sejam carregados do cache global de assemblies. Esse método deve ser usado apenas em cenários de execução remota, pois pode facilmente causar problemas na execução lado a lado.

Título Descrição
Como: Habilitar e desabilitar o redirecionamento automático de associação Descreve como associar um aplicativo a uma versão específica de um assembly.
Configurando o redirecionamento de associações de assemblies Explica como redirecionar referências de associação de assembly para uma versão específica de assemblies do .NET Framework.
Execução lado a lado em processo Discute como você pode usar a ativação de host de runtime lado a lado em processo para executar várias versões do CLR em um único processo.
Assemblies no .NET Fornece uma visão geral conceitual dos conjuntos.
domínios de aplicativo Fornece uma visão geral conceitual dos domínios do aplicativo.

Referência

Elemento <supportedRuntime>