Partager via


Exécution côte à côte dans le .NET Framework

Remarque

Cet article est spécifique à .NET Framework. Elle ne s’applique pas aux implémentations plus récentes de .NET, notamment .NET 6 et versions ultérieures.

L’exécution côte à côte est la possibilité d’exécuter plusieurs versions d’une application ou d’un composant sur le même ordinateur. Vous pouvez avoir plusieurs versions du Common Language Runtime et plusieurs versions d’applications et de composants qui utilisent une version du runtime, sur le même ordinateur en même temps.

L’illustration suivante montre plusieurs applications utilisant deux versions différentes du runtime sur le même ordinateur. Les applications A, B et C utilisent le runtime version 1.0, tandis que l’application D utilise la version 1.1 du runtime.

Exécution côte à côte de différentes versions du runtime,

Le .NET Framework se compose du Common Language Runtime et d’une collection d’assemblys qui contiennent les types d’API. Le runtime et les assemblys .NET Framework sont versionnés séparément. Par exemple, la version 4.0 du runtime est en fait la version 4.0.319, tandis que la version 1.0 des assemblys .NET Framework est la version 1.0.3300.0.

L’illustration suivante montre plusieurs applications utilisant deux versions différentes d’un composant sur le même ordinateur. L’application A et B utilisent la version 1.0 du composant tandis que l’application C utilise la version 2.0 du même composant.

Diagramme montrant l’exécution côte à côte d’un composant.

L’exécution côte à côte vous donne plus de contrôle sur les versions d’un composant auquel une application est liée, et plus de contrôle sur la version du runtime qu’une application utilise.

Avantages de l’exécution côte à côte

Avant Windows XP et le .NET Framework, les conflits DLL se sont produits parce que les applications n’ont pas pu faire la distinction entre les versions incompatibles du même code. Les informations de type contenues dans une DLL étaient liées uniquement à un nom de fichier. Une application n’avait aucun moyen de savoir si les types contenus dans une DLL étaient les mêmes types que celui avec lequel l’application a été créée. Par conséquent, une nouvelle version d’un composant peut remplacer une version antérieure et interrompre les applications.

L’exécution côte à côte et le .NET Framework fournissent les fonctionnalités suivantes pour éliminer les conflits DLL :

  • Assemblys avec nom fort.

    L'exécution côte à côte utilise des assemblys avec nom fort pour lier des informations de type à une version spécifique d'un assembly. Cela empêche une application ou un composant de se lier à une version non valide d’un assembly. Les assemblys avec nom fort permettent également à plusieurs versions d’un fichier d’exister sur le même ordinateur et d’être utilisés par les applications. Pour plus d’informations, consultez Assemblys avec nom fort.

  • Stockage de code prenant en compte la version.

    Le .NET Framework fournit un stockage de code prenant en charge la version dans le Global Assembly Cache. Le global assembly cache est un cache de code à l’échelle de l’ordinateur présent sur tous les ordinateurs avec le .NET Framework installé. Il stocke les assemblys basés sur les informations de version, de culture et d’éditeur, et prend en charge plusieurs versions de composants et d’applications. Pour plus d’informations, consultez Global Assembly Cache.

  • Isolement :

    À l’aide du .NET Framework, vous pouvez créer des applications et des composants qui s’exécutent en isolation. L'isolement est une fonctionnalité essentielle de l'exécution côte à côte. Il implique de connaître les ressources que vous utilisez et de partager des ressources en toute confiance entre plusieurs versions d’une application ou d’un composant. L’isolation inclut également le stockage de fichiers d’une manière spécifique à la version. Pour plus d’informations sur l’isolation, consultez Instructions pour la création de composants pour l’exécution côte à côte.

Compatibilité des versions

Les versions 1.0 et 1.1 du .NET Framework sont conçues pour être compatibles les unes avec les autres. Une application créée avec .NET Framework version 1.0 doit s’exécuter sur la version 1.1 et une application créée avec .NET Framework version 1.1 doit s’exécuter sur la version 1.0. Notez toutefois que les fonctionnalités d’API ajoutées dans la version 1.1 du .NET Framework ne fonctionneront pas avec la version 1.0 du .NET Framework. Les applications créées avec la version 2.0 s’exécutent uniquement sur la version 2.0. Les applications version 2.0 ne s’exécutent pas sur la version 1.1 ou antérieure.

Les versions du .NET Framework sont traitées comme une unité unique composée du runtime et de ses assemblys .NET Framework associés (un concept appelé unification d’assembly). Vous pouvez rediriger la liaison d’assembly pour inclure d’autres versions des assemblys .NET Framework, mais la substitution de la liaison d’assembly par défaut peut être risquée et doit être rigoureusement testée avant le déploiement.

Localisation des informations de version du runtime

Informations sur la version d’exécution avec laquelle une application ou un composant a été compilé et avec quelles versions du runtime l’application doit être exécutée sont stockées à deux emplacements. Lorsqu’une application ou un composant est compilé, des informations sur la version du runtime utilisée pour la compiler sont stockées dans l’exécutable managé. Les informations sur les versions d’exécution requises par l’application ou le composant sont stockées dans le fichier de configuration de l’application.

Informations de version du runtime dans l’exécutable managé

L’en-tête de fichier exécutable portable (PE) de chaque application managée et composant contient des informations sur la version du runtime avec laquelle elle a été générée. Le Common Language Runtime utilise ces informations pour déterminer la version la plus probable du runtime que l’application doit exécuter.

Informations de version du runtime dans le fichier de configuration de l’application

Outre les informations contenues dans l’en-tête de fichier PE, une application peut être déployée avec un fichier de configuration d’application qui fournit des informations de version d’exécution. Le fichier de configuration de l’application est un fichier XML créé par le développeur de l’application et fourni avec une application. L’élément< requiredRuntime> de la <section de démarrage>, s’il est présent dans ce fichier, spécifie les versions du runtime et les versions d’un composant pris en charge par l’application. Vous pouvez également utiliser ce fichier en test pour tester la compatibilité d’une application avec différentes versions du runtime.

Le code non managé, y compris les applications COM et COM+, peut avoir des fichiers de configuration d’application que le runtime utilise pour interagir avec du code managé. Le fichier de configuration de l’application affecte tout code managé que vous activez via COM. Le fichier peut spécifier les versions du runtime prises en charge, ainsi que les redirections d’assembly. Par défaut, les applications COM interop appelant du code managé utilisent la dernière version du runtime installée sur l’ordinateur.

Pour plus d’informations sur les fichiers de configuration d’application, consultez Configuration des applications.

Détermination de la version du runtime à charger

Le Common Language Runtime utilise les informations suivantes pour déterminer la version du runtime à charger pour une application :

  • Versions du runtime disponibles.

  • Versions du runtime prises en charge par une application.

Versions du runtime prises en charge

Le runtime utilise le fichier de configuration de l’application et l’en-tête de fichier exécutable portable (PE) pour déterminer la version du runtime qu’une application prend en charge. Si aucun fichier de configuration d’application n’est présent, le runtime charge la version du runtime spécifiée dans l’en-tête de fichier PE de l’application, si cette version est disponible.

Si un fichier de configuration d’application est présent, le runtime détermine la version appropriée du runtime à charger en fonction des résultats du processus suivant :

  1. Le runtime examine l’élément <SupportedRuntime> Element dans le fichier de configuration de l’application. Si une ou plusieurs des versions du runtime prises en charge spécifiées dans l’élément <supportedRuntime> sont présentes, le runtime charge la version du runtime spécifiée par le premier <élément supportedRuntime> . Si cette version n’est pas disponible, le runtime examine l’élément SupportedRuntime< suivant> et tente de charger la version du runtime spécifiée. Si cette version du runtime n’est pas disponible, les éléments <supportedRuntime> qui suivent sont examinés. Si aucune des versions du runtime prises en charge n’est disponible, le runtime ne parvient pas à charger une version du runtime et affiche un message à l’utilisateur (voir l’étape 3).

  2. Le runtime lit l’en-tête de fichier PE du fichier exécutable de l’application. Si la version du runtime spécifiée par l’en-tête de fichier PE est disponible, le runtime charge cette version. Si la version du runtime spécifiée n’est pas disponible, le runtime recherche une version du runtime déterminée par Microsoft pour être compatible avec la version du runtime dans l’en-tête PE. Si cette version est introuvable, le processus passe à l’étape 3.

  3. Le runtime affiche un message indiquant que la version du runtime prise en charge par l’application n’est pas disponible. Le runtime n’est pas chargé.

    Remarque

    Vous pouvez supprimer l’affichage de ce message à l’aide de la valeur NoGuiFromShim sous la clé de Registre HKLM\Software\Microsoft\. NETFramework ou utilisation de la variable d’environnement COMPLUS_NoGuiFromShim. Par exemple, vous pouvez supprimer le message pour les applications qui n’interagissent généralement pas avec l’utilisateur, comme les installations sans assistance ou les services Windows. Lorsque ce message est supprimé, le runtime écrit un message dans le journal des événements. Définissez la valeur de Registre NoGuiFromShim sur 1 pour supprimer ce message pour toutes les applications sur un ordinateur. Vous pouvez également définir la variable d’environnement COMPLUS_NoGuiFromShim sur 1 pour supprimer le message des applications s’exécutant dans un contexte utilisateur particulier.

Remarque

Une fois qu’une version du runtime est chargée, les redirections de liaison d’assembly peuvent spécifier qu’une autre version d’un assembly .NET Framework individuel doit être chargée. Ces redirections de liaison affectent uniquement l’assemblage spécifique redirigé.

Exécution côte à côte et noms d'assembly partiellement qualifiés

Comme il s’agit d'une source potentielle de problèmes de coexistence, les références d’assemblages partiellement qualifiées peuvent être utilisées uniquement pour lier des assemblages au sein d’un répertoire d’application. Évitez les références d’assembly partiellement qualifiées dans votre code.

Pour atténuer les références d’assembly partiellement qualifiées dans le code, vous pouvez utiliser l’élément qualifierAssembly< dans un fichier de configuration d’application pour qualifier entièrement les références d’assembly partiellement qualifiées qui se produisent dans le> code. Utilisez l’élément <qualifierAssembly> pour spécifier uniquement les champs qui n’ont pas été définis dans la référence partielle. L’identité d’assembly répertoriée dans l’attribut fullName doit contenir toutes les informations nécessaires pour qualifier pleinement le nom de l’assembly : nom de l’assembly, clé publique, culture et version.

L’exemple suivant montre l’entrée de fichier de configuration de l’application pour qualifier entièrement un assembly appelé myAssembly.

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

Chaque fois qu’une instruction de chargement d’assembly fait référence myAssembly, ces paramètres de fichier de configuration entraînent le runtime à traduire automatiquement la référence partiellement qualifiée myAssembly en référence complète. Par exemple, Assembly.Load(« myAssembly ») devient Assembly.Load(« myAssembly, version=1.0.0.0, publicKeyToken=..., culture=neutral »).

Remarque

Vous pouvez utiliser la méthode LoadWithPartialName pour contourner la restriction Common Language Runtime qui empêche les assemblys partiellement référencés d’être chargés à partir du Global Assembly Cache. Cette méthode est réservée aux scénarios de communication à distance, car elle génère souvent des problèmes dans l'exécution côte à côte.

Titre Descriptif
Procédure : Activer et désactiver la redirection de liaison automatique Décrit comment lier une application à une version spécifique d’un assembly.
Configuration de la redirection de liaison d’assemblage Explique comment rediriger des références de liaison d’assemblies vers une version spécifique des assemblies .NET Framework.
Exécution côte à côte in-process Explique comment utiliser l'activation d'hôte du runtime côte à côte in-process pour exécuter plusieurs versions du CLR dans un même processus.
Assemblys dans .NET Fournit une vue d’ensemble conceptuelle des assemblages.
Domaines d’application Fournit une vue d’ensemble conceptuelle des domaines d’application.

Référence

<Élément> supportedRuntime