本文概述了将代码从 .NET Framework 移植到 .NET(以前命名为 .NET Core)时应考虑的事项。 对于许多项目,从 .NET Framework 移植到 .NET 相对简单。 项目的复杂性决定了在初始升级项目文件后需要执行多少工作。
.NET 中提供应用模型的项目(如库、控制台应用和桌面应用)通常需要很少更改。 需要新应用模型(例如 从 ASP.NET 迁移到 ASP.NET Core)的项目需要更多工作。 旧应用模型中的许多模式具有可在转换期间使用的等效项。
Windows 桌面技术
为 .NET Framework 创建的许多应用程序都使用桌面技术,如 Windows 窗体或 Windows Presentation Foundation (WPF)。 Windows 窗体和 WPF 在 .NET 中都可用,但它们仍然是仅限 Windows 的技术。
升级 Windows 窗体或 WPF 应用程序之前,请考虑以下依赖项:
- .NET 的项目文件使用的格式与 .NET Framework 不同。
- 你的项目可能会使用 .NET 中不可用的 API。
- 第三方控件和库可能尚未移植到 .NET,并且仅可用于 .NET Framework。
- 项目使用 .NET 中不再可用的技术 。
.NET 使用 Windows 窗体和 WPF 的开源版本,并包括对 .NET Framework 的增强功能。
有关将桌面应用程序升级到 .NET 的教程,请参阅以下文章之一:
特定于 Windows 的 API
应用程序仍然可以在 .NET 支持的平台上使用 P/Invoke 调用本机库。 这项技术不限于 Windows。 但是,如果引用的库特定于 Windows,例如 user32.dll 或 kernel32.dll,则代码仅适用于 Windows。 对于希望应用运行的每个平台,必须查找特定于平台的版本,或使代码通用足以在所有平台上运行。
将应用程序从 .NET Framework 移植到 .NET 时,应用程序可能使用了 .NET Framework 提供的库。 许多 .NET Framework 中提供的 API 不会移植到 .NET,因为它们依赖于特定于 Windows 的技术,例如 Windows 注册表或 GDI+ 绘图模型。
Windows 兼容性包向 .NET 提供了大部分 .NET Framework API 图面,并通过 Microsoft.Windows.Compatibility NuGet 包提供。
有关详细信息,请参阅 使用 Windows 兼容性包将代码移植到 .NET。
.NET Framework 兼容性模式
.NET Framework 兼容性模式是在 .NET Standard 2.0 中引入的。 兼容性模式允许 .NET Standard 和 .NET 项目引用 .NET Framework 库,就像这些库是为项目的目标框架编译的一样。 但是,某些 .NET 实现可能支持比其他 .NET Framework 更大的区块。 例如,.NET Core 3.0 将 .NET Framework 兼容性模式扩展到 Windows 窗体和 WPF。 引用 .NET Framework 库不适用于所有项目,例如当库使用 WPF API 时,但它确实会解决很多阻碍移植的方案。 有关详细信息,请参阅 “分析依赖项”,将代码从 .NET Framework 移植到 .NET。
引用 .NET Framework 库在所有情况下都不起作用,因为它取决于使用哪些 .NET Framework API,以及项目的目标框架是否支持这些 API。 此外,某些 .NET Framework API 仅适用于 Windows。 .NET Framework 兼容性模式会解除限制许多移植场景,但你应该测试项目以确保它们在运行时正常工作。 有关详细信息,请参阅 分析依赖项以将代码从 .NET Framework 移植到目标框架。
SDK 样式项目中的目标框架更改
如前所述,.NET 的项目文件使用的格式与 .NET Framework 不同,称为 SDK 样式的项目格式。 即使未从 .NET Framework 移动到 .NET,仍应将项目文件升级到最新格式。 指定目标框架的方式在 SDK 样式项目中有所不同。 在 .NET Framework 中,该<TargetFrameworkVersion> 属性与指定 .NET Framework 版本的标识符对象一起使用。 例如,.NET Framework 4.7.2 如以下代码片段所示:
<PropertyGroup>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
</PropertyGroup>
SDK 样式项目使用不同的属性来标识目标框架(该 <TargetFramework> 属性)。 当目标是 .NET Framework 时,标识符以 net 开头,并以没有任何句点的 .NET Framework 版本结尾。 例如,用于定位 .NET Framework 4.7.2 的标识是 net472:
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
有关所有目标标识符的列表,请参阅 SDK 样式项目中的目标框架。
不可用的技术
.NET Framework 中的一些技术在 .NET 中不存在:
-
不支持创建其他应用程序域。 对于代码隔离,请使用单独的进程或容器作为替代方法。
-
远程处理用于跨不再受支持的应用程序域进行通信。 对于跨进程的简单通信,请考虑使用进程间通信(IPC)机制(例如 System.IO.Pipes 类或 MemoryMappedFile 类)作为远程处理的替代方法。 对于更复杂的方案,请考虑 使用 StreamJsonRpc 或 ASP.NET Core 等框架(使用 gRPC 或 RESTful Web API 服务)。
由于不支持远程处理,因此在委托对象上对
BeginInvoke()和EndInvoke()的调用将引发PlatformNotSupportedException。 -
CAS 是 .NET Framework 支持的沙盒技术,但在 .NET Framework 4.0 中已弃用。 它被安全透明度所取代,在 .NET 中不受支持。 改为使用操作系统提供的安全边界,例如虚拟化、容器或用户帐户。
-
与 CAS 类似,不再建议对 .NET Framework 应用程序使用安全透明度沙盒技术,在 .NET 中不受支持。 改为使用操作系统提供的安全边界,例如虚拟化、容器或用户帐户。
-
System.EnterpriseServices .NET 不支持 (COM+)。
Windows Workflow Foundation (WF)
.NET 不支持 WF。 有关替代方法,请参阅 CoreWF。
有关这些不受支持的技术的详细信息,请参阅 .NET 6+ 上不可用的 .NET Framework 技术。
跨平台
.NET(以前称为 .NET Core)设计为跨平台。 如果代码不依赖于特定于 Windows 的技术,则可以在其他平台上运行,例如 macOS、Linux 和 Android。 此类代码包括项目类型,例如:
- 图书馆
- 基于控制台的工具
- 自动化
- ASP.NET 网站
.NET Framework 是仅限 Windows 的组件。 当代码使用 Windows 特定的技术或 API(如 Windows 窗体和 WPF)时,代码仍可以在 .NET 上运行,但不能在其他操作系统上运行。
库或基于控制台的应用程序可以跨平台使用,而无需更改太多。 移植到 .NET 时,可能需要考虑到这一点,并在其他平台上测试应用程序。
.NET Standard 的未来
.NET Standard 是适用于多个 .NET 实现的 .NET API 的正式规范。 .NET Standard 背后的动机是在 .NET 生态系统中建立更大的统一性。 从 .NET 5 开始,已采用不同的建立统一性方法,这种新方法消除了在许多方案中对 .NET Standard 的需求。 有关详细信息,请参阅 .NET 5+ 和 .NET Standard。
.NET Standard 2.0 是支持 .NET Framework 的最后一个版本。
用于协助移植的工具
可以使用不同的工具来帮助自动执行升级的某些方面,而不是手动将应用程序从 .NET Framework 移植到 .NET。 移植复杂项目本身就是一个复杂的过程。 这些工具可能有助于这一旅程。
即使使用工具来帮助移植应用程序,也应查看本文中 移植部分时的注意事项 。
GitHub Copilot 应用现代化助手
GitHub Copilot 应用现代化是一个 GitHub Copilot 聊天助手,可帮助你规划和将项目升级到较新版本的 .NET、迁移到 Azure、更新依赖项并应用代码修复。 Azure 迁移由 .NET 的应用程序和代码评估提供支持
此聊天助手支持以下升级路径:
- 将项目从旧版 .NET 升级到最新版本。
- 将项目从 .NET Framework 升级到最新版本的 .NET。
- 使用新功能实现代码库的现代化。
- 将组件和服务迁移到 Azure。
它还适用于各种项目类型,例如:
- ASP.NET 和相关技术,如 MVC、Razor Pages、Web API
- Blazor
- Azure Functions
- Windows Presentation Foundation
- Windows 窗体
- 类库
- 控制台应用
何时使用:
如果希望 AI 支持的端到端体验将 .NET Framework 项目和依赖项升级到新式 .NET,请使用 GitHub Copilot 应用现代化,包括将应用程序迁移到 Azure 的评估、规划、修正和指南。
.NET 的应用程序和代码评估
适用于 .NET 的 Azure Migrate 应用程序和代码评估 提供代码和应用程序分析,以及规划云部署的建议。 它通过提供以开发人员为中心的源代码评估,帮助你自信地在云中运行业务关键型解决方案。 该工具还提供建议和示例来优化 Azure 的代码和配置,遵循行业最佳做法。
GitHub Copilot 应用现代化也使用此工具实现 .NET 体验。
何时使用:
使用 .NET 工具集的 Azure Migrate 应用程序和代码评估来评估现有代码库并将其迁移到 Azure 的建议。 Azure Migrate 应用程序和代码评估本质上是用于 .NET 体验的 GitHub Copilot 应用现代化的子集。
.NET 升级助手
.NET 升级助手是可在不同类型的 .NET Framework 应用上运行的命令行工具。 它旨在帮助将 .NET Framework 应用升级到 .NET。 运行该工具后, 在大多数情况下,应用将需要更多精力来完成升级。 该工具包括有助于完成升级的分析器安装。 此工具适用于以下类型的 .NET Framework 应用程序:
- Windows 窗体
- WPF
- ASP.NET MVC
- Console
- 类库
此工具使用本文中列出的其他工具,例如 try-convert,并指导升级过程。 有关该工具的详细信息,请参阅 .NET 升级助手概述。
何时使用:
当类似 GitHub Copilot 应用现代化的 AI 支持解决方案不可用时使用。
try-convert
该工具 try-convert 是一个 .NET 全局工具,可将项目或整个解决方案转换为 .NET SDK,包括将桌面应用移动到 .NET。 但是,如果项目具有复杂的生成过程(如自定义任务、目标或导入),则不建议使用此工具。
有关详细信息,请参阅 try-convert GitHub 存储库。
平台兼容性分析器
平台兼容性分析器分析您是否正在使用将在运行时引发异常的 PlatformNotSupportedException API。 尽管如果要从 .NET Framework 4.7.2 或更高版本移动,则很难找到其中一个 API,但最好进行检查。 有关在 .NET 上引发异常的 API 的详细信息,请参阅 始终在 .NET Core 上引发异常的 API。
有关详细信息,请参阅 平台兼容性分析器。
移植时的注意事项
将应用程序移植到 .NET 时,请考虑以下建议:
✔️ 请考虑使用 GitHub Copilot 应用现代化 升级项目。 GitHub Copilot 在移植时识别和修复不兼容功能非常强大。 它自动执行本文中详述的大部分手动步骤,并为你提供了继续升级路径的绝佳起点。
✔️ 请考虑先检查依赖项。 依赖项必须面向 .NET、.NET Standard 或 .NET Core。
✔️ 请从 NuGet packages.config 文件升级到 PackageReference 项目文件中的设置。 使用 Visual Studio 转换 package.config 文件。
✔️ 考虑升级到最新的项目文件格式,即使你尚未移植应用。 .NET Framework 项目使用过时的项目格式。 尽管为 .NET Core 及更高版本创建了最新的项目格式(称为 SDK 样式项目),但该格式也适用于 .NET Framework。 让项目文件采用最新格式,为将来移植应用提供了良好的基础。
✔️ 请将 .NET Framework 项目重新定位到至少 .NET Framework 4.7.2。 这可确保在 .NET Standard 不支持现有 API 的情况下提供最新的 API 替代项。
✔️ 请考虑面向 .NET 8,这是长期支持 (LTS) 版本。
✔️ 在 Windows 窗体和 WPF 项目中,请以 .NET 8+ 为目标。 .NET 8 及更高版本包含桌面应用的许多改进。
如果要升级一个可能与 .NET Framework 项目一起使用的库,请考虑将目标设定为 .NET Standard 2.0。 您还可以让您的库同时面向 .NET Framework 和 .NET Standard。
✔️ 如果迁移后收到缺少 API 的错误,请添加对 Microsoft.Windows.Compatibility NuGet 包 的引用。 .NET Framework API 图面的大部分内容可通过 NuGet 包提供给 .NET。