Как определить во время выполнения, что .NET версии 4.5 в настоящее время выполняет ваш код? - PullRequest
59 голосов
/ 15 декабря 2011

Я установил .NET 4.5 Developer Preview из http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27541,, который «заменяет» версию .NET 4.0.

Однако старый способ определения версии .NET Framework, похоже, возвращает 4.0 (точнее, 4.0.30319.17020 на моем ПК) вместо 4.5 (наверняка для обратной совместимости или?):

using System;

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

Как определить, что мой код действительно выполняется в .NET 4.5?

Ответы [ 6 ]

106 голосов
/ 17 декабря 2011

Необходимо провести четкое различие между CLR (т. Е. «Средой выполнения») и библиотеками фреймворка (т. Е. «Фреймворком»).Вы выполняете свой код с первым или с первым, ваш код компилируется и использует позднее.К сожалению, при использовании термина «.NET версия » обычно подразумевается целый пакет как среды выполнения, так и фреймворка, независимо от их отдельных версий, которые, как уже было сказано, могут различаться.

Вы можете обнаружить версии установленных фреймворков .Это, однако, не говорит вам, какой из них вы фактически используете во время выполнения.

Я не уверен насчет 4,5, но с 2,0 против 3,0 или 3,5 Environment.Version не помогло, поскольку оно всегдавернул 2.0, так как все эти версии фреймворка использовали CLR 2.0.Я предполагаю , что с framework 4.5 версия CLR по-прежнему равна 4.0, что объясняет, что Environment.Version возвращает 4.0.x даже в этом случае.

Техникадля вас может подойти проверка типа, метода или свойства в основных библиотеках (mscorlib, System.Core и т. д.), которые, как вы знаете, существуют, только начиная с конкретной версии .NET Framework.

Например, класс ReflectionContext кажется совершенно новым для .NET Framework 4.5 и удобно живет в mscorlib.Таким образом, вы могли бы сделать что-то вроде этого.

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

Имея все это, можно задаться вопросом, зачем вам знать, какую версию .NET вы используете.Просто попробуйте получить доступ к нужным вам функциям и, возможно, изящно откатиться к чему-то другому (которое было доступно в более старых версиях), если они отсутствуют.

Обновление : обратите внимание, что термин .NET 4.5относится ко всему пакету из нескольких сборок, которые составляют библиотеки базовых классов (BCL) и более (вместе именуемые «каркас»), а также саму среду выполнения, то есть CLR, обе из которых могут иметь разные версии, как уже было сказано.

Я не работаю на Microsoft и не понимаю реальных причин отсутствия (единой) функции или API для получения «версии .NET Framework», но я могу сделать обоснованное предположение.

  1. Не ясно, какую информацию, в частности, должна предоставлять такая функция / API. Даже отдельные сборки BCL не имеют общего (сборка / файл).) версия.Например, в .NET 3.0 и 3.5 mscorlib.dll имел версию 2.0.x, в то время как только в новых сборках WCF и WF было 3.0.Я думаю даже с .NET 3.5 у System.ServiceModel.dll все еще была версия 3.0.x.Что я пытаюсь сказать, нет единой версии на всех сборках фреймворка.Так что же должен вызывать вызов API, скажем, System.Environment.FrameworkVersion?Какое значение будет иметь версия (даже если она вернет «символическую» версию, такую ​​как 4.5, она не будет иметь большого значения, не так ли?).

  2. Слишкомспецифичные Некоторые новые функции могут появиться в SP к существующим версиям, а также стать частью новой версии.При проверке функций ваше приложение может отлично работать на предыдущих версиях, которые были обновлены, в то время как при явной проверке версии оно может излишне ограничиться самой новой версией.У меня нет примера из мира .NET для этого, но в целом (и в самой Windows, например, WMI) это может и произошло.

  3. Не хотел. Я мог бы себе представить, что метод для определения "версии фреймворка", который в настоящее время используется приложением, даже не желательный для них предоставлять. Существует длинная и безобразная история ошибок проверки версий (см. Параграф «Не проверять версию» для понятий, которые также применимы к .NET), в родном мире / Win32. Например, люди неправильно использовали API GetVersion и GetVersionEx, проверяя только то, что они запускают версию, которая, как они знали, была самой новой, когда они писали свое приложение. Таким образом, когда приложение запускалось в более новой версии Windows, оно не запускалось, даже несмотря на то, что функции , которые они действительно использовали, все еще были там. Microsoft могла бы рассмотреть подобные проблемы и, следовательно, даже не предоставила некоторый API в .NET.

Кстати, именно это Microsoft рекомендует в разделе замечаний функции GetVersion:

Идентификация текущей операционной системы обычно не лучший способ определить, присутствует ли конкретная функция операционной системы. Это связано с тем, что в операционной системе могут быть добавлены новые функции в распространяемой DLL. Вместо использования GetVersionEx для определения платформа операционной системы или номер версии, проверьте наличие самой функции.

Блог команды Windows также может что-то сказать .

Я знаю, что все это касалось Windows и собственного программирования, но концепция и опасности одинаковы для приложений .NET, среды и CLR.

Я бы сказал, что проверка функций с (изящным) резервом, таким образом, является гораздо более надежным и надежным способом проверки совместимости вашего приложения. Если вы хотите, чтобы ваше приложение работало только с определенной версией .NET или новее, не делайте ничего особенного и рассчитывайте на обратную совместимость самого .NET.

28 голосов
/ 09 марта 2016

Чтобы точно определить, какой патч .NET используется в вашем приложении, выполните этот вызов, чтобы найти номер сборки mscorlib:

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

В настоящее время он возвращает мне 4.6.1055.0, что соответствует .NET 4.6.1.

25 голосов
/ 14 марта 2012

.NET Framework 4.5 - это обновление на месте до 4.0.Это означает, что если вы работаете в среде выполнения версии 4.0 или 4.5, и установлена ​​4.5, то вы, безусловно, работаете на 4.5.Ваш чек может пойти следующим образом.

Давайте назовем обе среды выполнения: 4.0 и 4.5 версии с версией 4.0 .

  1. Проверьте, работаете ли вы в среде исполнения с версией 4.0:

    • Если ваша сборка скомпилирована для целевого .NET 4.0 или
    • Environment.Version.Major == 4 && Environment.Version.Minor == 0

    тогда вы работаете в среде исполнения с версией 4.0.

  2. Проверьте, является ли ваша среда исполнения версии 4.0 на самом деле версией 4.0 или 4.5,проверив установленную версию:

    • Под ключом HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client проверьте значение _Version_.Если он начинается с "4.0", вы работаете в среде исполнения 4.0, если он начинается с "4.5", вы работаете в среде исполнения 4.5.
7 голосов
/ 22 декабря 2017

Джеймс дает отличный ответ о получении "версии продукта" mscorlib.dll во время выполнения:

(using System.Diagnostics;)

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

Это хорошо работает, но вы можете получить более детальный результат, изучив System.dll вместо:

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

Обратите внимание, что небольшая разница заключается в использовании сборки для typeof(Uri) вместо typeof(int), поскольку первая определяется в System.dll, а не для mscorlib.dll для последней. Для простой консольной программы на C #, предназначенной для .NET 4.7.1 , разница, как сообщается в настоящее время в моей системе, следующая: :

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

Что касается того, является ли различие полезным или как использовать более подробную информацию, это будет зависеть от конкретной ситуации.

5 голосов
/ 07 декабря 2012

Вы можете проверить, установлен ли .NET Framework 4.5 или .NET Framework 4 , проверив подключ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full в реестре на значение DWORD с именем Release.Наличие этого DWORD указывает на то, что на этом компьютере установлена ​​ .NET Framework 4.5 .Значение Release является номером версии.Чтобы определить, установлена ​​ли окончательная версия .NET Framework 4.5 , проверьте значение, равное или большее 378389.

.
2 голосов
/ 15 декабря 2011

Из того, что я понял из онлайн-ресурсов, .NET 4.5 будет действовать аналогично (хотя и не полностью так же), как 3.5 для 2.0: ваш номер версии останется прежним (если вы запустите код 3.5, версия CLR будет2.0), и он будет действовать как обновление существующего CLR 4.0.

Таким образом, вы сможете обновить сосуществующий 2.0 до 3.5, а 4.0 - до 4.5.

Что остается неяснымв том случае, если будет возможно создавать (или работать над существующими) проекты в 4.0 без необходимости их обновления до 4.5: в настоящее время вы можете создавать проекты 2.0 или 3.5 в Visual Studio 2010, но, возможно, это будет не так для 4.0 и4.5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...