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.
-
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 ?).
-
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.
-
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
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! :)
0 votes
@HansPassant: oui, c'est vrai, je veux dire ici .NET 4.5, merci :) Corrigé
6 votes
Eh bien, reliez les points, la dernière phrase de votre question est donc impossible à répondre. La seule chose logique à faire est de vérifier si la version 4.5 est installée. Si c'est le cas, il n'y a aucun moyen que la révision 4.0 exécute votre programme.
0 votes
Pourquoi diable vous importez de la version de l'environnement d'exécution? Il me semble que vous essayez de résoudre un problème de la mauvaise manière.
1 votes
HansPassant, CodyGray : supposons simplement que j'installe .NET 4.5 et maintenant je suis confus, est-ce que ça fonctionne vraiment ou y a-t-il eu un problème lors de l'installation et j'utilise toujours .NET 4.0 (pour les applications Windows et surtout les hôtes ASP.NET MVC). Je ne veux PAS faire de tests de performances de GC ou utiliser la "détection de fonctionnalités" (voir la réponse de Christian.K) pour savoir quel runtime exécute mon code. Beaucoup d'améliorations / nouvelles fonctionnalités sont introduites par .NET 4.5 et ça me paraît déroutant qu'il n'y ait aucun moyen de détecter que le code est exécuté par lui (pas pour détecter que v4.5 est installé, ce qui est trivial, mais qu'il fonctionne réellement!).
0 votes
Au fait, j'utilise également les "vérifications" suivantes :
var version = typeof(int).Assembly.GetName().Version; var version2 = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(); var version3 = typeof(int).Assembly.ImageRuntimeVersion;
- même résultat, c'est-à-dire 4.0.0.0 ou 4.0.30319 partout :)1 votes
@EvereQ Désolé de le dire, mais d'après le libellé de votre dernier commentaire ci-dessus, vous ne semblez toujours pas comprendre la différence entre .NET dans son ensemble (package), le CLR et/ou les bibliothèques du framework. Quoi qu'il en soit, j'ai ajouté quelques informations supplémentaires à ma réponse sur pourquoi je pense que ce que vous demandez n'est peut-être même pas possible ou souhaité.
0 votes
@Christian.K Je ne ferais pas de telles hypothèses à mon sujet, cependant merci de mettre à jour votre réponse. Pour vous montrer à quel point vous pouvez avoir tort avec moi et avec .NET 4.5 en général, veuillez répondre à ce qui suit : Que pensez-vous, le GC fait-il partie du CLR ou non ? Maintenant, lisez par exemple : blogs.microsoft.co.il/blogs/sasha/archive/2011/09/17/… Voyez combien d'améliorations ont été apportées au GC de .NET 4.5 ? Il est donc important dans CERTAINS scénarios de détecter quel exécuteur de code exécute votre code et cela n'a rien à voir avec les différences entre .NET dans son ensemble, le CLR et les bibliothèques du framework :)
2 votes
@EverQ Je n'essayais pas de te faire dire quelque chose que tu n'as pas dit ou de faire des suppositions (c'est pourquoi j'ai dit "tu ne semblais toujours pas..."). Si tu as pris offense, désolé. Quoi qu'il en soit, concernant ton exemple, tu peux constater que le nouveau CLR (celui qui apparemment est toujours v4.0 même s'il est livré avec .NET 4.5). Exemples ci-dessous.