¿Cómo detecto en el tiempo de ejecución que .NET versión 4.5 está ejecutando actualmente su código?

Instalé .NET 4.5 Developer preview de http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541 , que ‘reemplaza’ la versión de .NET 4.0.

Sin embargo, la forma antigua de detectar la versión de .NET framework parece devolver 4.0 (más precisamente 4.0.30319.17020 en mi PC), en lugar de 4.5 (¿seguro que es compatible con versiones anteriores?):

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

¿Cómo puedo detectar que mi código realmente lo ejecuta .NET 4.5?

Debe hacer una distinción clara entre el CLR (es decir, el “tiempo de ejecución”) y las bibliotecas de marcos (es decir, el “marco”). Ejecuta su código en o con el primero, su código se comstack y usa el último. Desafortunadamente, cuando se usa el término ” versión .NET”, generalmente se hace referencia al paquete completo de tiempo de ejecución y marco, independientemente de sus versiones individuales que, como se ha dicho, pueden diferir.

Puede detectar las versiones de marco instaladas . Sin embargo, eso no te dice cuál usas realmente en tiempo de ejecución.

No estoy seguro acerca de 4.5, pero con Environment.Version 2.0. 3.0 o 3.5. Environment.Version versión no fue de ayuda, ya que siempre devolvía 2.0 ya que todas esas versiones de framework estaban usando CLR 2.0. Supongo que con el marco 4.5 la versión de CLR sigue siendo 4.0, lo que explicaría que Environment.Version devuelve 4.0.x incluso en ese caso.

Una técnica que puede funcionar para usted es buscar un tipo, método o propiedad en las bibliotecas centrales (mscorlib, System.Core, etc.) que usted sabría que solo existía comenzando con una versión particular de .NET Framework.

Por ejemplo, la clase ReflectionContext parece ser totalmente nueva con .NET framework 4.5 y convenientemente reside en mscorlib . Entonces podrías hacer algo como esto.

  public static bool IsNet45OrNewer() { // Class "ReflectionContext" exists from .NET 4.5 onwards. return Type.GetType("System.Reflection.ReflectionContext", false) != null; } 

Habiendo dicho todo esto, uno podría preguntarse por qué necesita saber qué versión de .NET está usando. Simplemente intente acceder a las funciones que necesita y posiblemente retroceda graciosamente a otra cosa (que estaba disponible en versiones anteriores) si no están presentes.

Actualización : Tenga en cuenta que el término .NET 4.5 se refiere a todo el paquete de varios ensambles que conforman las bibliotecas de clases base (BCL) y más (colectivamente llamado “framework”) más el tiempo de ejecución en sí, es decir, el CLR, ambos pueden tener diferentes versiones, como se ha dicho.

No trabajo para Microsoft y no tengo idea de las razones reales detrás de la falta de una función (única) o API para obtener “la versión de .NET Framework”, pero puedo hacer una conjetura.

  1. No está claro qué información, en particular, debería proporcionar esa función / API. Incluso los ensamblajes individuales del BCL no comparten una versión común (ensamblaje / archivo). Por ejemplo, con .NET 3.0 y 3.5, mscorlib.dll tenía la versión 2.0.x mientras que solo los nuevos ensamblados de WCF y WF tenían algo 3.0. Creo que incluso con .NET 3.5 el System.ServiceModel.dll todavía tenía la versión 3.0.x. Lo que bash decir es que no existe una versión unificada en todas las asambleas del marco. Entonces, ¿a qué debería responder una llamada de API como, por ejemplo, System.Environment.FrameworkVersion ? ¿Qué valor tendría la versión (incluso si devolviera la versión “simbólica” como 4.5, sería de poco valor, ¿no?).

  2. Demasiado específico Algunas características nuevas pueden llegar en los SP a las versiones existentes, además de ser parte de una nueva versión. Al hacer la comprobación de funciones, su aplicación podría funcionar perfectamente en versiones anteriores , que se han actualizado, mientras que con la comprobación de versiones explícitas podría restringirse innecesariamente a la versión más reciente. No tengo un ejemplo del mundo de .NET para esto, pero en general (y en el propio Windows, por ejemplo, WMI) puede suceder y de hecho sucedió.

  3. No deseado. Me podría imaginar que un método para calcular “la versión del marco” que está siendo utilizado actualmente por una aplicación ni siquiera es deseable para ellos. Existe un largo y profano historial de verificaciones de versiones (consulte el párrafo “No verificar versión” para conocer los conceptos que también se aplican a .NET), en el mundo nativo / Win32. Por ejemplo, las personas usaron las API GetVersion y GetVersionEx incorrectamente, al comprobar que ejecutaban la versión que sabían que era la más reciente cuando escribieron su aplicación. Por lo tanto, cuando la aplicación se ejecutaba en una versión más nueva de Windows, no se ejecutaba, a pesar de que las funciones que realmente estaban utilizando todavía están allí. Microsoft podría haber considerado problemas como ese y, por lo tanto, ni siquiera proporcionó alguna API en .NET.

Por cierto, esto es lo que recomienda Microsoft en la sección de comentarios de la función GetVersion:

Identificar el sistema operativo actual generalmente no es la mejor manera de determinar si una característica particular del sistema operativo está presente. Esto se debe a que el sistema operativo puede tener nuevas características agregadas en una DLL redistribuible. En lugar de utilizar GetVersionEx para determinar la plataforma del sistema operativo o el número de versión, pruebe la presencia de la característica en sí.

El Blog del equipo de Windows también tiene algo que decir al respecto.

Sé que todo esto era sobre Windows y la progtwigción nativa, pero el concepto y los peligros son los mismos para las aplicaciones .NET que el framework y el CLR.

Yo diría que la comprobación de funciones con un repliegue (elegante) es, por lo tanto, una forma mucho más confiable y sólida de garantizar que su aplicación sea compatible con versiones anteriores. Si solo desea que su aplicación funcione con una versión específica de .NET o posterior, no haga nada especial y cuente con la compatibilidad con versiones anteriores de .NET.

.NET Framework 4.5 es una actualización in situ a 4.0. Esto vagamente significa que si está ejecutando en una versión 4.0 o 4.5 de tiempo de ejecución, y 4.5 está instalado, entonces ciertamente se está ejecutando en 4.5. Su cheque puede ir de la siguiente manera.

Llamemos a los tiempos de ejecución 4.0 y 4.5 de tiempos de ejecución 4.0 .

  1. Verifique si se está ejecutando en un tiempo de ejecución 4.0-versionado:

    • Si su ensamblado está comstackdo para destino .NET 4.0, o
    • Environment.Version.Major == 4 && Environment.Version.Minor == 0

    entonces estás ejecutando un tiempo de ejecución de 4.0 versiones.

  2. Compruebe si el tiempo de ejecución de la versión 4.0 es en realidad la versión 4.0 o 4.5, verificando la versión instalada:

    • Debajo de la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client , compruebe el valor _Version_ . Si comienza con "4.0" se está ejecutando en el tiempo de ejecución 4.0, si comienza con "4.5" se está ejecutando en el tiempo de ejecución 4.5.

Para determinar exactamente qué parche de .NET está ejecutando su aplicación, puede realizar esta llamada para encontrar la versión de comstackción de mscorlib:

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

Actualmente devuelve 4.6.1055.0 para mí, que corresponde a .NET 4.6.1.

Puede probar si .NET Framework 4.5 o .NET Framework 4 está instalado al marcar la HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full en el registro para un valor DWORD llamado Release . La existencia de este DWORD indica que .NET Framework 4.5 se ha instalado en esa computadora. El valor de Release es un número de versión. Para determinar si está instalada la versión de lanzamiento final de .NET Framework 4.5 , verifique que el valor sea igual o mayor que 378389 .

James proporciona la gran respuesta de obtener la “versión del producto” de mscorlib.dll en tiempo de ejecución:

( using System.Diagnostics; )

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

Esto funciona bien, pero puede obtener un resultado más preciso examinando System.dll en su lugar:

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

Observe que la pequeña diferencia es utilizar el ensamblado para typeof(Uri) lugar de typeof(int) , ya que el primero se define en System.dll en lugar de mscorlib.dll para el último. Para un progtwig de consola C # simple que se dirige a .NET 4.7.1 , la diferencia, tal como se informa actualmente en mi sistema, es la siguiente :

… \ Microsoft.NET \ Framework \ v4.0.30319 \ mscorlib.dll 4.7. 2600 .0 … \ Microsoft.NET \ Framework \ v4.0.30319 \ System.dll 4.7. 2556 .0

En cuanto a si la distinción es útil o cómo usar la información más detallada, eso dependerá de la situación particular.

Según lo que entendí de los recursos en línea, .NET 4.5 actuará de forma similar (aunque no del todo igual) que 3.5 para 2.0: el número de versión seguirá siendo el mismo (si ejecuta el código 3.5, la versión de CLR será 2.0), y actuará como una actualización del CLR 4.0 existente.

Por lo tanto, podrá actualizar 2.0 coexistente a 3.5 y actualizar 4.0 a 4.5.

Lo que no está claro es si será posible realizar (o trabajar en proyectos existentes) en 4.0 sin tener que actualizarlos a 4.5: actualmente puede hacer proyectos de 2.0 o 3.5 en Visual Studio 2010, pero tal vez no sea el mismo para 4.0 y 4.5.