确定需要哪个.NET Core运行时

时间:2017-05-29 10:17:11

标签: asp.net-core .net-core

我发现了一些有关.NET Core SDK /运行时/工具版本控制困难的有趣文章,例如:

但是我仍然不知道如何在实践中处理所有这些:

  1. 给定一个具有许多.Net Core依赖项的项目。如何确定最终用户计算机上需要提供哪个版本的运行时?
  2. 运行时版本是否需要完全匹配,或者最终用户计算机上安装的运行时是否比所需版本更新?
  3. 我想说我想坚持运行时的某些LTS版本。如何确定我需要引用的软件包的版本?如何确保没有引用更新的包?
  4. 哦,还有一个:

    1. 一旦我知道最终用户计算机上需要哪个运行时版本,我如何(以编程方式)确定该版本的运行时(或更新的,向后兼容的)是否可用?

1 个答案:

答案 0 :(得分:15)

首先,让我们看一下通过dotnet yourapp.dll运行可移植.NET Core应用程序时会发生什么:

  • muxer可执行文件(Windows上为dotnet.exe)从hostfxr旁边的host\fxr\下方的文件夹中加载主机框架解析程序(dotnet.exe)的一个版本。
  • 主机框架解析程序会查看yourapp.runtimeconfig.json(如果在使用dotnet exec时配置了其他文件,则会查找您要定位的框架)。这会提取框架名称(Microsoft.NETCore.App)和版本(例如1.1.0)。
  • 然后查看可用版本的shared\Microsoft.NETCore.App文件夹(基于框架名称)。
  • 根据yourapp.runtimeconfig.json中的可用版本和框架版本,它确定要使用的版本。或者它可能会决定错误并抱怨所需的版本不可用。
    • 这是困难的,有时令人困惑的部分。

目前(.NET Core 1.0),框架解析器将使用可用于runtimeconfig.json中指定的主要版本和次要版本的最新补丁版本,但不会低于runtimeconfig.json指定的版本。例如。如果运行时配置指定1.1.2,则将使用1.1.1运行时,但如果只有1.1.0可用,则会记录错误。在次要版本中也没有版本前滚。因此,如果只安装了1.0.0,则运行时配置设置为1.1.*的应用程序将触发错误。

对于.NET Core 2.0,如果未找到匹配的次要版本,则计划进行次要版本前滚 - 如果安装了1.0.51.1.2运行时,则运行时配置为{的应用程序{1}}将在1.0.4运行时运行。如果仅安装了1.0.5,则会在1.1.2上运行相同的应用。如果仅安装1.1.2,则无法运行相同的应用。有关此更改的详细信息和讨论,请参阅GitHub issue for .NET Core 2+ Version Binding

让我们看一下运行时配置中的值来自何处。当您定位框架2.0.0时,您使用的工具将确定:

  • 使用哪个NuGet包(+版本),以便您获得能够编译的编译引用。
  • 要写入netcoreapp1.1
  • 的版本

在csproj文件中,要使用的框架版本由属性

确定
yourapp.runtimeconfig.json

如果未指定此值,则工具将使用它知道的最新版本  对于.NET Core 1.0和1.1。

对于.NET Core 2.0,可移植应用程序默认使用补丁版本<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion> ,自包含应用程序将使用工具知道的最新版本。之所以进行此更改,是因为工具(CLI&#34; SDK&#34; / Visual Studio)更新和运行时更新已同时发布,因此应用程序默认需要在目标系统上安装新的运行时。如果未安装该运行时,则会发生错误。如果托管人需要几天的时间才能赶上测试和安装更新,那就太糟糕了。通过明确设置0,仍然可以强制执行/需要该版本。

关于包:1. *工具使用的包是元包。因此,引用<RuntimeFrameworkVersion>Microsoft.NETCore.App会引入许多其他NuGet包。 .NET Core 2.0和.NET Standard 2.0不再是这种情况 - 软件包是扁平的,包含您需要的所有内容。此外,当您创建NuGet包时,这些包将不再是生成的包的依赖项。它们仅用于编译引用,但NETStandard.Library知道要为自包含应用程序引入哪些附加包。

以前,使用Microsoft.NETCore.App版本NETStandard.Library构建的库会导致消耗.NET Core 1.0应用程序包含大量已更新的DLL文件,这些文件实际上是1.6.1的一部分。我不知道这是否意味着LTS策略将涵盖或不涵盖最终使用这些DLL的应用程序。并且很难看出它们属于哪个.NET Core版本,因为它们源自的软件包版本通常是.NET Core 1.14.0.*4.1.*

对于ASP.NET核心软件包,它更容易,因为它们的版本为4.3.*1.0.*,因此您可以看到哪些&#34;分支&#34;它们起源于您,并且您可以通过在csproj文件中指定NuGet包来更好地控制所使用的版本。

回顾一下,让我们回到原来的问题:

  
      
  1. 给定一个具有许多.Net Core依赖项的项目。如何确定需要在哪个版本的运行时上可用   最终用户机器?
  2.   

这里真正的依赖是将1.1.*的哪个版本写入Microsoft.NETCore.App文件。必须安装相同的主要和次要编号以及相同或更高的修补程序编号的版本,将使用最新的修补程序版本。安装.NET Core 2.0解析程序时,将使用具有相同主编号的最高版本,但将优先使用相同主编号和次编号的版本。

如果仅安装了具有较新主要版本的运行时,则无法在目标系统上运行该应用程序。 (例如yourapp.runtimeconfig.json app和1.0.5运行时)

  
      
  1. 运行时版本是否需要完全匹配,或者最终用户计算机上安装的运行时是否比所需版本更新?
  2.   

运行时配置的版本是最低限度的。有关选择正确版本的较新运行时的信息,请参见上文。

  
      
  1. 我想说我想坚持运行时的某些LTS版本。如何确定我需要引用的软件包的版本?怎么样   我可以确保没有引用更新的包吗?
  2.   

2.0.0的版本将自动从目标框架中推断出来(例如Microsoft.NETCore.App =&gt; netcoreapp1.0,修补程序版本取决于您使用的工具版本)。要覆盖版本,请按上面的说明设置1.0.*属性。

如果传递新的NuGet包,例如通过从.NET Core 1.0应用程序中消耗Newtonsoft.Json 10.0.0(请参阅GitHub issue),可能会将一些额外的DLL添加到项目的输出中。这些是运行时的一部分的较新版本的DLL,但是会覆盖运行时的版本。

如果您确实希望确保不使用任何FTS版本,则需要在csproj文件中明确引用所有这些软件包,以便NuGet降级所用软件包的版本(和发出包降级警告)。

这里的问题是,在1.0和1.1软件包中没有修复问题的情况。如果将来支持1.0和2.0但1.1不再是问题,我们将不得不看看如何处理这个问题。 (尽管社区肯定会有压力/要求发布更新的1.1版本,即使微软的支持不包括在内)。

如果您使用<RuntimeFrameworkVersion>或更高版本,那么这些实施包将从您应用的依赖关系图中删除,并在部署时不再予以考虑。这是冲突解决逻辑的一部分,它知道新的扁平包包含与各个包相同的DLL文件。

  
      
  1. 一旦我知道最终用户计算机上需要哪个运行时版本,我如何(以编程方式)确定该版本的   运行时(或更新的,向后兼容的)可用吗?
  2.   
  1. 扫描2.0旁边的shared\Microsoft.NETCore.App子文件夹,并实现主机使用的相同逻辑。
  2. PInvoke到dotnet.exe旁边hostfxr.dll中最新host\fxr的原生代码。但这样做相当复杂。