Dotnet Core应用跨框架版本运行

dotNET跨平台 今天

以下文章来源于老王Plus ,作者老王Plus的老王

老王Plus一个二十年的老全栈的技术碎碎念

有时候,我们真想用新框架,可也真不想改代码。

有一个前置的知识需要了解,就是微软 Dotnet Core 框架的版本体系。我前边的文章「Dotnet Core使用特定的SDK&Runtime版本」有详细的说明,可以去翻翻看。

前言

有一个旧应用,是在 Dotnet Core 2.1 下编译的服务端应用。本来跑的很好。最近,服务器上的 Dotnet Core Runtime 框架统一升级到 3.1,于是,这个程序就出问题了。

运行时,会报以下的错误:

% dotnet theapp.dll It was not possible to find any compatible framework versionThe framework 'Microsoft.NETCore.App', version '2.1.0' was not found.  - The following frameworks were found:      3.1.11 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]

You can resolve the problem by installing the specified framework and/or SDK.

The specified framework can be found at:  - https://aka.ms

为什么会这样?

这个情况,源于微软的默认框架运行规则:Dotnet Core 应用运行时,要求运行时的版本,主版本号与编译程序的SDK版本相同,次版本号等于或高于编译程序的SDK版本。

比方我们上边这个程序,编译 SDK 的版本是 2.1.0,因此默认可以运行在装有 Dotnet Runtime 2.1.0 - 2.1.28 的所有运行时下。 

但是,现实的情况,我们希望升级框架的主版本。要知道,现在 Dotnet 5.0 已经成为常规版本,6.0 也已经到了第五个 Preview 了,升级是必然的。

那么,升级完框架后,如何升级已有的应用?

如何升级已有的应用?

通常会有这么几种方式,来升级已有的应用:

1. 升级应用的编译 SDK 版本

说白了,就是在指定的新的 SDK 版本下,重新编译重新生成。

指定特定的 SDK 版本,只需要打开对应工程的.csproj文件,在里面加入下面的内容:

<PropertyGroup>  <TargetFramework>netcoreapp3.1</TargetFramework></PropertyGroup>

这里面,我们以指定 Dotnet 3.1 为例子。

这儿要注意,5.0 之前,TargetFramework 对应的名称为 netcoreapp,例如 netcoreapp2.1、netcoreapp3.1,而 5.0 之后,微软把名称改了,变成了 net5.0、net6.0。 

这个方式,算是几种方式中,比较麻烦的一种。最基本的前提是,要有工程的源代码。

如果没有源代码,又该怎么办呢?

2. 显式覆盖运行时

Dotnet 命令行有一个参数,可以显式指定使用特定运行时版本来覆盖编译版本对应的运行时。

这个参数就是 --fx-version。

使用时,命令如下:

% dotnet --fx-version "3.1.11" theapp.dll 

还是上面的例子,这样一个命令,就可以让 2.1.0 下编译的应用,在 3.1.11 的运行时下运行。而这个 3.1.11,就是安装的运行时的版本号。 

如果不知道已安装的运行时的准确版本号,可以用以下命令查询:

% dotnet --list-runtimesMicrosoft.AspNetCore.App 3.1.11 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]Microsoft.NETCore.App 3.1.11 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

3. 显式覆盖 .runtimeconfig.json 文件

这是另一种显式改变运行时的方式。

我们观察项目的编译结果目录,会看到一个跟随应用的 .runtimeconfig.json 文件。以上面的例子来说,会叫做 theapp.runtimeconfig.json。如果没有,可以手工创建一个。

看一下它的内容:

{  "runtimeOptions": {    "tfm": "netcoreapp2.1",    "framework": {      "name": "Microsoft.NETCore.App",      "version": "2.1.0"    }  }}

在这个配置文件中,微软提供了一个前滚策略,可以通过 rollForward 来定义如果找不到要求的运行时版本,程序应该如果使用其它版本的运行时。

关于 rollForward 的详细说明,在「Dotnet Core使用特定的SDK&Runtime版本」文章中也有详细的说明,这儿就不再赘述了。我们直接看内容本例的修改内容:

{  "runtimeOptions": {    "tfm": "netcoreapp2.1",    "framework": {      "name": "Microsoft.NETCore.App",      "version": "2.1.0",      "rollForward": "major"    }  }}

比较前后两个文件,只是在中间加了一行:"rollForward": "major",就让这个程序在高版本的运行时下正常运行了。

重要的问题

嗯,虽然上面写了三种方式跨框架运行,但是,你一定要注意,跨框架运行,不像看上去那么简单。

你可以去骂微软。微软在做 Dotnet 主要版本的升级时,是有破坏性的更改的。也就是说,后面的版本,并不是完全兼容前边的版本的。某些类或方法,在版本升级时,都可能做了新的设计和变更,一些方法会被取消,甚至连所属的软件包,都可能发生变化。

因此,做完上面的工作后,要做仔细全面的测试。一个应用可以工作得很好,不等于每个应用都可以。

额外的内容:SDK 与 Runtime

在 Dotnet Core 体系中,SDK 与 Runtime 是完全分离的。虽然我们每次安装时,SDK 与 Runtime 总是一起安装。

SDK 的版本,仅仅是一个版本号,不同的版本之间,不具有本质的区别。版本号仅仅表示这个 SDK 支持到哪一个版本的内容。因此,我们可以从当前的 SDK 版本构建任何以前的版本,而不仅仅是当前安装的 SDK 版本。

这个话说起来有点绕,举个例子,我的机器上只装了 Dotnet Core 5.0 SDK,我也可以构建 Dotnet Core 2.0 的应用,而不需要非得装 Dotnet Core SDK 2.0。

当我们 SDK 来构建应用时,SDK 会根据构建的版本,来下载适当的引用包。这些包包含构建应用所需要的占位符、元数据和程序集。而编译系统会根据这些引用程序集来编译代码,以生成应用程序。

所以,实际在开发环境中,只需要安装最新版本的 SDK,就可以了。

运行时则不一样。在早期 Dotnet Framework 系列时,框架是向后兼容的,Framework 4.5 的框架完全可以运行 Framework 2.0 的应用程序。但到了 Dotnet Core,就不一样了,它被明确的版本所定义和区别。旧版本编译的程序,在高版本的运行时上,不一定能正常运行。 

所以,如果你装了一堆 SDK 和 Runtime,你其实可以这样清理:SDK 保留最新的版本,Runtime 保留各个主版本中最新的版本。好在,各个版本仅以目录的形式存在,清理起来很简单。

总结

Dotnet Core 跨框架运行是一个很复杂的内容,如果你从头去翻微软的文档,那会很头大。

因此,我这个文章,用尽量简单的方式,给大家入个门。

喜欢就来个三连,让更多人因你而受益

(0)

相关推荐

  • 【翻译】.NET 5 Preview8发布

    今天,.NET 5预览8发布了,对于.NET5.0的功能开发已经完成了,这必须要排除待处理的bug,预览8是最后一次预览版本.预计11月正式的.NET5.0版本发布之前还将发布两个正式之前的候选版本, ...

  • 【翻译】.NET 5 Preview2发布

    在4月2日,发布了.NET 5.0 Preview2,这次发布对一些功能和性能做了相关的改进,同时后面也会实施5.0版本更多的功能,其中一些功能设计目前也在dotnet/designs中显示,在.NE ...

  • 在 Visual Studio 2019 中为 .NET Core WinForm App 启用窗体设计器

    当我们在使用 Visual Studio 2019 非预览版本开发 Windows Forms App (.NET Core) 应用程序时是不能使用窗体设计器的.即使在窗体文件上右击选择"显 ...

  • 一文看懂:什么是.NET Core以及.NET Core能做什么?

    我们都知道.NET Core是一个可以用来构建现代.可伸缩和高性能的跨平台软件应用程序的通用开发框架.可用于为Windows.Linux和MacOS构建软件应用程序. 与其他软件框架不同,.NET C ...

  • .Net Core 智能提示汉化包

    在.Net Core 2.x 版本,Microsoft 官方没有提供 .Net Core 正式版的多语言安装包.因此,我们在用.Net Core 2.x 版本作为框架目标编写代码时,智能提成是英文的. ...

  • 【翻译】.NET 5 Preview 1 发布

    去年年底,我们发布了.NET Core 3.0和3.1.这些版本添加了桌面应用程序模型Windows Forms(WinForms)和WPF,ASP.NET Blazor用于构建SPA应用程序和用于构 ...

  • .NET Core和.NET Standard有什么不同

    近日,微软发布了.NET Core 2.0,但是开发人员中间仍然存在一些疑惑,就是.NET Core..NET Standard.Xamarin和.NET Framework有什么不同. .NET F ...

  • Linux服务器部署.Net Core笔记:三、安装.NetCore运行环境

    Linux服务器部署.Net Core笔记:三、安装.NetCore运行环境

  • WPF dotnet core 的 Blend SDK Behaviors 库

    之前版本是通过安装 Blend SDK 支持 Behaviors 库的,但是这个方法都是通过引用 dll 的方式,不够优雅.在升级到 dotnet core 3.0 的时候就需要使用 WPF 官方团队 ...

  • 打造跨平台.NET Core后台服务

    续之前讲的在TopShelf上部署ASP.NET Core程序,作为后台服务运行,自从.NET Core 3.0出现以后,出现了自带的Generic Host,使得自托管服务变为可能.这种方式和Top ...

  • 如何为.NETCore安装汉化包智能感知

    引言 具体不记得是在群里还是什么地方有人问过,.NETCore有没有汉化包,答案是有,目前微软已经为我们提供了.NETCore多种语言的语言包.下面看看如何安装与使用吧. 本文介绍: 如何安装这些下载 ...