Как я могу программно найти версию среды выполнения .NET?

Мне нужно решение, чтобы предоставить мне версию .СЕТЬ времени выполнения как полной структуры, так и .NET Core.

На машине со следующими версиями .СЕТЬ:

Full: 4.7.2
Core: 2.1.104

Бег:

RuntimeInformation.FrameworkDescription

Дает мне:

Full: .NET Framework 4.7.2558.0
Core: .NET Core 4.6.26212.01

Бег:

Environment.Version

Дает мне:

Full: 4.0.30319.42000
Core: 4.0.30319.42000

Как я могу точно получить версии времени выполнения для разных платформ, зная, что параметр реестра недоступен за пределами Окна.

Что вы имеете в виду, говоря «получить исполняемые версии для разных платформ»? Ваш код точно дает вам версии .NET, а RuntimeInformation.OSDescription предоставит вам ОС. Что вы имеете в виду под "параметром реестра"? Вы хотите посмотреть реестр, если вы работаете в Windows?

Philippe 10.04.2018 12:07

Под «версией времени выполнения» вы подразумеваете версию CLR, верно?

Henk Holterman 10.04.2018 12:25

@HenkHolterman, я считаю, что версия CLR - это то, что возвращает Environment.Version, но он возвращает одну и ту же версию как для ядра, так и для полной структуры. В данном случае мне нужна версия фреймворк. Документы, кажется, еще больше сбивают с толку, ссылка, которую я разместил в своем комментарии выше, относится к получению версии фреймворка, а затем к интерпретации версии на основе возвращенной версии CLR. Но это не говорит о .NET Core.

MaYaN 10.04.2018 12:31

Вы видите ту же версию CLR в выходных данных Environment.Version, потому что, начиная с .NET Framework 4.6, и Framework, и Core работают в среде CLR, совместимой с .NET Standard 2.0: они действительно одинаковы (что, конечно, не отвечает на ваш реальный вопрос) .

McGuireV10 10.04.2018 15:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
24
5
8 793
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Для .NET Framework:

using System;
...
string ver = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;

и для .NET Core:

using System.Reflection;
using System.Runtime.Versioning;
...
string ver = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;

Выход:

.NETFramework,Version=v4.5.1
.NETCoreApp,Version=v2.0

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

Другая часть головоломки, которая, вероятно, всегда будет невозможной, заключается в том, что данное приложение может ссылаться на множество целей. Под капотом, например, вы можете использовать библиотеки .NET Standard 2.x и .NET Standard 1.x. Я сомневаюсь, что когда-нибудь будет хороший способ получить изображение полный всех целей, стоящих за данным набором выполняющихся сборок ...

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

McGuireV10 10.04.2018 15:52

Подход рефлексии на полнофункциональной платформе возвращает null для TargetFrameworkAttribute, поэтому его нельзя там использовать.

MaYaN 10.04.2018 15:56

Я считать, это на самом деле один из отчетов об ошибках, с которыми вы столкнетесь, если будете преследовать все эти перекрестные ссылки github - что, вероятно, означает, что в долгосрочной перспективе отражение будет поддерживать любые другие API, которые они добавляют. В любом случае удачи!

McGuireV10 10.04.2018 16:00

Для .NET Framework подход будет возвращать, какая .NET Framework выполняет «целевое» приложение, а не то, что оно установлено в системе.

Alex Ghiondea - MSFT 12.04.2018 22:26

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

Alex Ghiondea - MSFT 12.04.2018 22:43

В последней версии .NET Core 3.0 RC1 сообщается, что свойство System.Runtime.InteropServices.RuntimeInformation.FrameworkD‌​escription будет возвращать правильную версию текущей среды выполнения .NET, в которой выполняется сборка. Также свойство System.Environment.Version также должно работать должным образом.

Chezzwizz 20.09.2019 06:36

Если вы хотите узнать, какая версия .NET Framework установлена ​​на компьютере, вам следует использовать задокументированный ключ реестра Release Key. Этот ключ регистрируется в системе при установке .NET Framework.

Это публично задокументировано здесь: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies

Вы должны написать код, который будет читать этот раздел реестра и сопоставлять его с реальной версией .NET Framework. Вот код, который делает это для версий .NET Framework между 4.5 и 4.7.1. Вы можете дополнительно настроить это по своему усмотрению. (из https://github.com/dotnet/corefx/blob/master/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.NetFx.cs#L33)

    private static Version GetFrameworkVersion()
    {
        using (RegistryKey ndpKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"))
        {
            if (ndpKey != null)
            {
                int value = (int)(ndpKey.GetValue("Release") ?? 0);
                if (value >= 528040) 
                    return new Version(4, 8, 0);

                if (value >= 461808) 
                    return new Version(4, 7, 2);

                if (value >= 461308)
                    return new Version(4, 7, 1);

                if (value >= 460798)
                    return new Version(4, 7, 0);

                if (value >= 394802)
                    return new Version(4, 6, 2);

                if (value >= 394254)
                    return new Version(4, 6, 1);

                if (value >= 393295)
                    return new Version(4, 6, 0);

                if (value >= 379893)
                    return new Version(4, 5, 2);

                if (value >= 378675)
                    return new Version(4, 5, 1);

                if (value >= 378389)
                    return new Version(4, 5, 0);

                throw new NotSupportedException($"No 4.5 or later framework version detected, framework key value: {value}");
            }

            throw new NotSupportedException(@"No registry key found under 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' to determine running framework version");
        }
    }

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

Для .NET Core нет раздела реестра, который вы можете проверить. Однако вы можете использовать расположение сборки, содержащей System.Object, для определения версии, на которой работает ваш код.

    public static Version GetVersion()
    {
        string runtimePath = System.IO.Path.GetDirectoryName(typeof(object).Assembly.Location);
        // Making the assumption that the path looks like this
        // C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.6
        string version = runtimePath.Substring(runtimePath.LastIndexOf('\\') + 1);

        return new Version(version);
    }

Интересно, но, к сожалению, не работает с автономными приложениями. проголосовали независимо.

MaYaN 13.04.2018 11:12

Спасибо! Да, для автономных приложений это не сработает. Но для тех, кто знает среду выполнения во время разработки, и это не изменится при развертывании приложения.

Alex Ghiondea - MSFT 14.04.2018 16:48

значение для 4.7.2 = 461808, поэтому if (value> = 461808) вернет новую версию (4, 7, 2);

Moon Waxing 04.05.2018 03:47

@MoonWaxing Изменено в соответствии с вашим предложением

Karel Kral 10.04.2019 15:37

Другие вопросы по теме