60 votes

Comment détecter à l'exécution que la version 4.5 de .NET est actuellement en cours d'exécution dans votre code?

J'ai installé la version de développement .NET 4.5 d'aperçu à partir de http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541, qui 'remplace' la version .NET 4.0.

Cependant, l'ancienne manière de détecter la version du framework .NET semble renvoyer 4.0 (plus précisément 4.0.30319.17020 sur mon PC), au lieu de 4.5 (sûrement probablement pour la compatibilité ascendante, ou?):

using System;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var version = Environment.Version;
            Console.WriteLine(version.ToString());
            Console.ReadKey();
        }
    }
}

Comment puis-je détecter que mon code est vraiment exécuté par .NET 4.5?

0 votes

Lorsque vous installez .NET, il ne 'remplace' rien. Allez voir dans C:\Windows\Microsoft.NET\Framework et vous verrez un dossier pour chaque framework que vous avez installé. Si vous souhaitez modifier le framework sous lequel votre application est compilée, il vous suffit d'ouvrir les propriétés de votre Projet dans l'Explorateur de solutions, puis de sélectionner le framework correct dans la liste déroulante "Framework cible".

13 votes

Il n'y a pas de "CLR 4.5", il utilise toujours la version CLR 4.0.30319.

3 votes

@tobias86: .NET 4.5 est différent. Il REMPLACE .NET 4.0 sur votre PC! :)

107voto

Christian.K Points 18883

Il est nécessaire de faire une distinction claire entre le CLR (c'est-à-dire le "runtime") et les bibliothèques du framework (c'est-à-dire le "framework"). Vous exécutez votre code sur ou avec le premier, votre code est compilé contre et utilise le second. Malheureusement, lorsque l'on utilise le terme ".NET version", on fait généralement référence à l'ensemble du package comprenant à la fois le runtime et le framework, quelles que soient leurs versions individuelles qui - comme cela a été dit - peuvent différer.

Vous pouvez détecter les versions du framework installées. Cela ne vous dit cependant pas laquelle vous utilisez réellement à l'exécution.

Je ne suis pas sûr pour 4.5, mais avec 2.0 contre 3.0 ou 3.5, Environment.Version n'était d'aucune aide car il retournait toujours 2.0 car toutes ces versions du framework utilisaient le CLR 2.0. Je présume qu'avec le framework 4.5, la version du CLR est toujours 4.0, ce qui expliquerait que Environment.Version renvoie toujours 4.0.x même dans ce cas.

Une technique qui pourrait fonctionner pour vous est de rechercher un type, une méthode ou une propriété dans les bibliothèques de base (mscorlib, System.Core, etc.) qui n'existait qu'à partir d'une certaine version du framework .NET.

Par exemple, la classe ReflectionContext semble être totalement nouvelle avec le framework .NET 4.5 et se trouve opportunément dans mscorlib. Vous pourriez donc faire quelque chose comme ceci.

  public static bool IsNet45OrNewer()
  {
      // La classe "ReflectionContext" existe à partir de .NET 4.5.
      return Type.GetType("System.Reflection.ReflectionContext", false) != null;
  }

Tout cela étant dit, on pourrait se demander pourquoi vous avez besoin de savoir quelle version de .NET vous utilisez. Essayez simplement d'accéder aux fonctionnalités requises et éventuellement de basculer élégamment vers autre chose (disponible dans les anciennes versions) si elles ne sont pas présentes.

Mise à jour : Notez que le terme .NET 4.5 fait référence à l'ensemble du package de plusieurs assemblies qui composent les bibliothèques de classes de base (BCL) et plus encore (collectivement appelé "framework") ainsi que le runtime lui-même, c'est-à-dire le CLR - qui peuvent avoir des versions différentes, comme cela a été dit.

Je ne travaille pas pour Microsoft et je n'ai pas d'aperçu des raisons réelles derrière l'absence d'une (seule) fonction ou API pour obtenir "la version du framework .NET", mais je peux faire une supposition éclairée.

  1. Il n'est pas clair quelles informations en particulier une telle fonction/API devrait fournir. Même les assemblies individuels du BCL n'ont pas un numéro de version (d'assembly/fichier) commun. Par exemple, avec .NET 3.0 et 3.5, le mscorlib.dll avait la version 2.0.x tandis que seuls les nouveaux assemblies de WCF et WF avaient quelque chose en 3.0. Je pense même qu'avec .NET 3.5 le System.ServiceModel.dll avait encore la version 3.0.x. Ce que j'essaie de dire, c'est qu'il n'y a pas de version unifiée sur tous les assemblies du framework. Alors, que devrait renvoyer un appel API comme, disons, System.Environment.FrameworkVersion ? Quelle serait la valeur de la version (même si elle renvoyait la version "symbolique" comme 4.5, cela aurait peu de valeur, n'est-ce pas ?).

  2. Trop spécifique. Certaines nouvelles fonctionnalités peuvent arriver dans des packs de service pour des versions existantes, en plus de faire partie d'une nouvelle version. En testant les fonctionnalités, votre application peut très bien fonctionner sur des versions antérieures qui ont été mises à jour, alors qu'avec une vérification explicite de version, elle pourrait se limiter inutilement à la dernière version. Je n'ai pas d'exemple du monde .NET pour cela, mais en général (et dans Windows lui-même, par exemple le WMI) cela peut arriver et a déjà eu lieu.

  3. Non souhaité. J'imagine qu'une méthode pour déterminer "la version du framework" actuellement utilisée par une application n'est même pas souhaitable de leur part. Il existe une longue et sombre histoire de fausses idées sur les vérifications de version (voir le paragraphe "Ne pas vérifier la version" pour des concepts qui s'appliquent également à .NET), dans le monde natif/Win32. Par exemple, les gens utilisaient mal les APIs GetVersion et GetVersionEx, en vérifiant uniquement qu'ils exécutaient la version qu'ils savaient être la plus récente lorsqu'ils ont écrit leur application. Ainsi, lorsque l'application était exécutée sur une version plus récente de Windows, elle ne fonctionnait pas, même si les fonctionnalités qu'ils utilisaient vraiment étaient toujours là. Microsoft pourrait avoir pris en compte ces problèmes et donc n'avoir pas fourni une API dans .NET.

À propos, c'est ce que Microsoft recommande dans la section des remarques de la fonction GetVersion :

Identifier le système d'exploitation actuel n'est généralement pas la meilleure façon de déterminer si une fonctionnalité particulière du système d'exploitation est présente. Cela est dû au fait que le système d'exploitation peut avoir eu de nouvelles fonctionnalités ajoutées dans un DLL redistribuable. Au lieu d'utiliser GetVersionEx pour déterminer la plateforme du système d'exploitation ou le numéro de version, testez la présence de la fonctionnalité elle-même.

Le blog de l'équipe Windows a également quelque chose à dire à ce sujet.

Je sais que tout cela concernait Windows et la programmation native, mais le concept et les dangers sont les mêmes pour les applications .NET, le framework et le CLR.

Je dirais que la vérification des fonctionnalités avec un retour en arrière (gracieux) est donc un moyen beaucoup plus fiable et robuste de s'assurer que votre application est compatible descendante. Si vous souhaitez seulement que votre application fonctionne avec une version spécifique de .NET ou plus récente, ne faites rien de spécial du tout et comptez sur la compatibilité ascendante de .NET lui-même.

0 votes

Bien sûr, merci pour la réponse! Je pensais aussi à l'approche "modernizr" :), cependant la méthode JavaScript pour détecter les fonctionnalités n'est pas une façon courante de faire de telles choses en .NET :) Si vous continuez votre réponse, probablement la prochaine étape en plus de "gracefully fallback", sera d'utiliser un "polyfill" pour substituer les fonctionnalités de .NET 4.5 :D etc. Je pense simplement que MSFT devrait avoir un autre moyen de détecter la version d'exécution pour exécuter le code :)

4 votes

Je recommanderais à tout le monde de lire également le billet de blog suivant de Scott Hanselman : hanselman.com/blog/…. Surtout, j'aime l'idée d'ajouter dans app.config pour presque tous les types d'applications, SAUF ASP.NET si votre application nécessite .NET 4.5. (l'utilisateur sera invité à installer .NET 4.5 s'il n'est pas disponible). Ce n'est pas exactement de la détection, cependant :(... Quoi qu'il en soit, mon +1 pour demander à l'équipe ASP.NET d'ajouter également le support de ce paramètre de configuration.

1 votes

Je veux juste ajouter ma raison de vérifier si le framework .net 4.5 est installé : stackoverflow.com/a/15715990/423356 (le bug de la suppression de MemoryCache.Default sur une application web)

32voto

James L Points 6068

Pour déterminer exactement quelle version de .NET votre application exécute, effectuez cet appel pour trouver le numéro de build de mscorlib :

System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion

Actuellement, il me renvoie 4.6.1055.0, ce qui correspond à .NET 4.6.1.

25voto

Govert Points 6031

Le Framework .NET 4.5 est une mise à niveau sur place vers la version 4.0. Cela signifie approximativement que si vous utilisez une version 4.0 ou 4.5 de l'environnement d'exécution, et que la version 4.5 est installée, alors vous utilisez certainement la version 4.5. Votre vérification pourrait se dérouler de la manière suivante.

Appelons les environnements d'exécution 4.0 et 4.5 des environnements d'exécution version 4.0.

  1. Vérifier si vous utilisez un environnement d'exécution version 4.0:

    • Si votre assembly est compilé pour cibler .NET 4.0, ou
    • Environment.Version.Major == 4 && Environment.Version.Minor == 0

    alors vous utilisez un environnement d'exécution version 4.0.

  2. Vérifiez si votre environnement d'exécution version 4.0 est en réalité la version 4.0 ou 4.5, en vérifiant la version installée:

    • Sous la clé HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client, vérifiez la valeur _Version_. Si elle commence par "4.0", vous utilisez l'environnement d'exécution 4.0, si elle commence par "4.5", vous utilisez l'environnement d'exécution 4.5.

8voto

Glenn Slayden Points 1995

James fournit la excellente réponse pour récupérer la "version du produit" de mscorlib.dll à l'exécution :

(using System.Diagnostics;)

FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion

Cela fonctionne bien, mais vous pouvez obtenir un résultat plus précis en examinant plutôt System.dll :

FileVersionInfo.GetVersionInfo(typeof(Uri).Assembly.Location).ProductVersion

Remarquez la légère différence qui consiste à utiliser l'assembly pour typeof(Uri) au lieu de typeof(int), puisque le premier est défini dans System.dll contrairement à mscorlib.dll pour le second. Pour un simple programme console en C# ciblant .NET 4.7.1, la différence, telle que rapportée actuellement sur mon système, est la suivante:

...\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll   4.7.2600.0 ...\Microsoft.NET\Framework\v4.0.30319\System.dll    4.7.2556.0

Quant à savoir si cette distinction est utile ou comment utiliser les informations plus détaillées, cela dépendra de la situation particulière.

5voto

Vipul Points 608

Vous pouvez vérifier si le .NET Framework 4.5 ou le .NET Framework 4 est installé en vérifiant la sous-clé HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full dans le registre pour une valeur DWORD nommée Release. L'existence de ce DWORD indique que le .NET Framework 4.5 a été installé sur cet ordinateur. La valeur de Release est un numéro de version. Pour déterminer si la version finale du .NET Framework 4.5 est installée, vérifiez une valeur qui est égale ou supérieure à 378389.

2 votes

La clé de registre et la fonction IsNet45OrNewer() de Christian.K sont parfaites. Merci, @Vipul!

2 votes

De MSDN concernant cette valeur de registre : msdn.microsoft.com/en-us/library/hh925568.aspx '''Vous devez disposer de privilèges administratifs pour exécuter cet exemple'''

1 votes

Cette réponse ne répond pas à la question

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X