Определить which.NET необходима среда выполнения Core

Я нашел несколько интересных статей о трудностях управления версиями .NET Core SDK / runtime/tooling, например:

однако я все еще не знаю, как справиться со всем этим на практике:

  1. учитывая проект с рядом Зависимости .Net Core. Как определить, какая версия среды выполнения должна быть доступна на компьютере конечных пользователей?
  2. должна ли версия среды выполнения точно соответствовать, или среда выполнения, установленная на компьютере конечных пользователей, может быть новее требуемой версии?
  3. предположим, я хочу придерживаться некоторой версии LTS среды выполнения. Как я могу определить версию пакетов, на которые мне нужно ссылаться? Как я могу убедиться, что нет новых пакетов ссылка?

О, и еще одно:

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

1 ответов


во-первых, давайте посмотрим, что происходит, когда портативное приложение .NET Core запускается через dotnet yourapp.dll:

  • исполняемый файл muxer (dotnet.exeв windows) загружает версию распознавателя host framework (hostfxr) из папки под host\fxr\ рядом с dotnet.exe.
  • решатель host framework смотрит на yourapp.runtimeconfig.json (или другой файл, если он настроен при использовании dotnet exec), чтобы узнать, какие рамки вы нацелены. Это извлекает имя фреймворка (Microsoft.NETCore.App) и a версия (например 1.1.0).
  • затем он заглядывает внутрь shared\Microsoft.NETCore.App папка (на основе имен) для существующих версий.
  • на основе доступных версий и версии фреймворка из yourapp.runtimeconfig.json он определяет, какую версию использовать. Или он может решить ошибиться и пожаловаться, что Требуемая версия недоступна.
    • это трудная и иногда запутанная часть.

в настоящее время (.NET Core 1.0) , Framework resolver будет использовать последнюю версию исправления, доступную для основной и дополнительной версии, указанной в runtimeconfig.json но нет версии ниже, чем runtimeconfig.json указывает. Е. Г. а 1.1.2 среда выполнения будет использоваться, если во время выполнения config задает 1.1.1, но если только 1.1.0 доступно, он зарегистрирует ошибку. Существует также нет версии roll-forward через второстепенные версии. Таким образом, приложение с конфигурацией времени выполнения установлено в 1.0.0 вызовет ошибку, если только какой-нибудь 1.1.* is установленный.

для .NET Core 2.0 запланирован откат младшей версии в случае, если не найдена соответствующая младшая версия-если 1.0.5 и 1.1.2 runtime установлены, приложение с конфигурацией времени выполнения 1.0.4 о 1.0.5 во время выполнения. Если бы только!--14--> установлен, то же приложение будет работать на 1.1.2. Если бы только!--25--> установлен, то же приложение не сможет работать. См.проблема GitHub для привязки версии .NET Core 2+ для получения подробной информации и обсуждение этого изменения.

давайте посмотрим, откуда берется значение в конфигурации среды выполнения. Когда вы нацеливаете фреймворк netcoreapp1.1, инструмент, который вы используете, определит:

  • какой пакет NuGet (+версия) использовать, чтобы вы могли компилировать ссылки на компиляцию.
  • какую версию записать в yourapp.runtimeconfig.json

в файле csproj версия используемой платформы определяется собственность

<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>

если это значение не указано, инструмент будет использовать новейшая версия он знает о для .NET Core 1.0 и 1.1.

для .NET Core 2.0 портативные приложения будут использовать версию патча 0 по умолчанию и автономные приложения будут использовать последнюю версию, о которой знает инструмент. Это изменение выполняется, поскольку обновления tooling (CLI "SDK" / Visual Studio) и обновления среды выполнения были выпущены одновременно время, чтобы приложения требовали установки новой среды выполнения в целевых системах по умолчанию. Если эта среда выполнения не была установлена, произойдет ошибка. Это было плохо, если хостерам требуется несколько дней, чтобы догнать тестирование и установку обновлений. Версия все еще может быть применена / требуется, установив <RuntimeFrameworkVersion>явно.

о пакетах: пакеты, 1.* tooling использует мета-пакеты. Так что ссылки Microsoft.NETCore.App или NETStandard.Library вытащил бы много других пакетов NuGet. Это больше нет случая для .NET Core 2.0 и .NET Standard 2.0-пакеты являются плоскими и содержат все, что вам нужно. Кроме того, при создании пакета NuGet пакеты будут больше не быть зависимостями результирующего пакета. Они используются только для ссылок на компиляцию, за исключением Microsoft.NETCore.App зная, какие дополнительные пакеты, чтобы вытащить для автономных приложений.

ранее библиотека, построенная с NETStandard.Library версия 1.6.1 приведет потребление приложений .NET Core 1.0, чтобы содержать много обновленных файлов DLL, которые на самом деле являются частью .NET Core 1.1. Я не знаю, означает ли это, что политики LTS будут охватывать или не охватывать приложения, которые заканчиваются этими DLL. И трудно понять, к какой версии .NET Core они принадлежат, поскольку версии пакетов, из которых они происходят, обычно 4.0.*, 4.1.* и 4.3.*.

для ASP.NET основные пакеты, это намного проще, так как они версионные 1.0.* и 1.1.* так вы можете увидеть, из какой "ветви" они происходят, и у вас больше контроля над версиями, используемыми, указав пакеты NuGet в файле csproj.

чтобы резюмировать, давайте вернемся к исходным вопросам:

  1. учитывая проект с рядом зависимостей .Net Core. Как определить, какая версия среды выполнения должна быть доступна на машина конечных пользователей?

реальная зависимость здесь в том, что версия Microsoft.NETCore.App пишется . Версия того же основного и меньшего числа и того же или более высокого номера патча должна быть установлена, будет использоваться последняя версия патча. При установке распознавателя .NET Core 2.0 вместо него будет использоваться самая высокая версия с тем же основным номером, но предпочтительной будет версия с тем же основным и второстепенным номером.

если установлены только среды выполнения с более новыми основными версиями, приложение не может быть запущено на целевая система. (например,1.0.5 app и только 2.0.0 во время выполнения)

  1. должна ли версия среды выполнения точно соответствовать, или среда выполнения, установленная на компьютере конечных пользователей, может быть новее требуемой версии?

версия конфигурации среды выполнения является жестким минимумом. Для выбора правильной версии новых сред выполнения см. выше.

  1. предположим, я хочу придерживаться некоторой версии LTS во время выполнения. Как я могу определить версию пакетов, на которые мне нужно ссылаться? Как могу ли я убедиться, что ссылки на новые пакеты отсутствуют?

версия Microsoft.NETCore.App будет автоматически выводиться из целевой структуры (например,netcoreapp1.0 =>1.0.*, версия заплаты в зависимости от версии tooling вы используете). Чтобы переопределить версию, установите <RuntimeFrameworkVersion> свойство, как обсуждалось выше.

если новые пакеты NuGet ссылаются транзитивно, например, потребляя Newtonsoft.Json 10.0.0 из приложения .NET Core 1.0 (см. выпуск GitHub), некоторые дополнительные библиотеки DLL могут быть добавлены к выходу проекта. Это более новые версии DLL, которые являются частью среды выполнения, но переопределяют версии из среды выполнения.

если вы действительно хотите убедиться, что вы не используете никаких версий FTS, вам нужно будет явно ссылаться на все эти пакеты в вашем файле csproj, чтобы NuGet понизил версию используемых пакетов (и испустил пакет понижающих предупреждений).

проблема здесь в том, что не было случая, когда проблема не была исправлена в пакетах 1.0 и 1.1. Если это будет проблемой в будущем, когда 1.0 и 2.0 будут поддерживаться, но 1.1 больше не будет, нам придется посмотреть, как это будет обрабатываться в каждом случае. (хотя, конечно, есть давление/запросы от сообщества, чтобы выпустить обновленные версии 1.1, а также, Даже если не охвачены поддержкой Microsoft).

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

  1. как только я узнаю, какая версия среды выполнения требуется на компьютере конечных пользователей, как я могу определить (программно), если эта версия среда выполнения (или более новая, обратная совместимость Один) доступен?
  1. сканирование shared\Microsoft.NETCore.App вложенные папки рядом с dotnet.exe и реализовать ту же логику, используемую хостом.
  2. PInvoke в родной код последней hostfxr.dll на host\fxr рядом с dotnet.exe. Но это довольно сложно сделать.