升级Windows 窗体应用的概述

本文可帮助你了解将 Windows 窗体 应用从 .NET Framework 升级到 .NET 所涉及的内容。 Windows 窗体 在 .NET 上受到支持,并持续获得积极投入,包括新式控件、高 DPI 改进和辅助功能更新。 如果你维护现有的Windows 窗体应用,并希望利用这些改进或迁移到受支持的.NET版本,本文适用于你。

本文介绍升级的原因、可用的升级路径以及使升级顺利完成的准备工作。 它还介绍了哪些.NET框架技术在.NET中没有等效项,如何使用Windows兼容性包填补 API 空白,以及重大更改如何影响应用。

有关如何升级的示例,请参阅使用GitHub Copilot现代化将Windows 窗体应用升级到.NET

升级原因

.NET Framework 是仅适用于 Windows 的闭源运行时,并且不再获得功能更新。 虽然它继续接收受支持版本的安全修补程序,但它不会受益于.NET的性能工作、语言改进或积极投资。 如果你正在维护一个基于 .NET Framework 的 Windows 应用,升级到 .NET 后,你将能够使用一个速度更快、功能更强,且以开放方式持续积极开发的平台。

在.NET版本上保持最新状态也很重要。 每个 .NET 版本都有明确的支持期限,而在已停止支持的版本上运行的应用将不再接收安全补丁和修复更新。 在终止支持之前升级,以保持受保护状态。

.NET在运行时启动、吞吐量和内存使用量方面提供有意义的性能改进。 .NET上的桌面应用还受益于正在进行的功能投资:

  • 更新的控件、辅助功能改进和高 DPI 改进。
  • 更好地与Windows集成。 某些功能(如Windows 11上的深色模式)仅在.NET可用。
  • 较新的 C# 和Visual Basic语言功能和改进的工具。
  • 面向.NET的 NuGet 包的丰富生态系统。

.NET 每年都会发布一个新的主要版本,在长期支持(LTS)版本和标准期限支持(STS)版本之间交替:

  • LTS 版本 支持三年,通常是首选稳定性的生产应用的最佳选择。
  • STS 版本 支持 24 个月,当你希望更快地采用新功能时非常有用。

围绕这些日期规划升级节奏,以便应用始终处于受支持的版本。 有关当前支持的版本和支持终止日期,请参阅.NET版本、修补程序和支持

升级路径

大多数升级分为两类之一。 确定应用适用的路径,然后使用本文中的指南和工具完成工作。

  • 从.NET框架到.NET:最重要的变化。

    项目文件格式、某些 API 和某些技术不同。 在开始之前,请查看先决条件、评估依赖项并规划 API 差距。

    应用在.NET上生成并运行后,可以选择采用较新的模式,例如appsettings.json配置、依赖项注入或云服务。 采用这些模式与迁移到 .NET 的现代化改造是彼此独立的,并非完成升级所必需的。 有关想法和指导,请参阅从 .NET Framework 升级到.NET后的现代化

  • 从较旧的.NET版本升级到较新的版本:较小的范围升级。

    主要任务是更新目标框架标识符、查看所跨越版本中的重大变更,以及更新 NuGet 依赖项。

从 .NET Framework 升级到 .NET

从 .NET Framework 升级到 .NET 是本部分最重要的升级路径和主要重点。

Important

尽管 .NET 是一种跨平台技术,但适用于 .NET 的 Windows 桌面应用仍然仅限于 Windows 平台。

一项更改是项目文件格式。 .NET使用 SDK 样式的项目格式,这比旧格式更简洁。 你可以将项目文件转换为 SDK 样式,同时仍以 .NET Framework 为目标框架,这样可在实际迁移期间减少变更范围,并为后续工作提供更好的基线。

并非所有.NET框架 API 都可用于.NET。 某些 API 存在于表面上,但在运行时引发 PlatformNotSupportedException 。 Windows兼容性包(NuGet 包)通过提供对特定于Windows API(Microsoft.Windows.Compatibility例如Windows注册表、Windows事件日志等)的访问,填补了其中许多空白。 有关详细信息,请参阅使用 Windows 兼容性包将代码移植到.NET

一些.NET框架技术在.NET中没有等效项,需要替代方法,例如应用程序域、代码访问安全性(CAS)和Windows Workflow Foundation。 有关详细信息,请参阅“不可用.NET框架技术”部分。

审查第三方依赖项。 仅面向 .NET Framework 的控件和库可能无法处理.NET。 首选以 .NET Standard 2.0 或直接以 .NET 为目标的 NuGet 包。 对于尚未移植的包,请查找社区替代项,或检查Windows兼容性包是否涵盖所需的 API。

.NET 版本之间的升级

从一个 .NET 版本升级到另一个版本(例如,从 .NET 9 升级到 .NET 10)所需的工作量通常比从 .NET Framework 进行现代化改造更小。 核心任务是将项目文件中的 <TargetFramework> 属性更新为新的目标框架标识符。 例如,将 net9.0-windows 更改为 net10.0-windows

更新目标框架前,请查阅要跨越的每个版本的重大变更文档。 破坏性变更可能表现为行为上的变化、影响二进制兼容性或源代码兼容性,或者更改设计时的行为。 即使是次要版本差距也会引入影响应用的更改。 查看.NET 中的重大更改,并按你要跨越升级的版本范围进行筛选。

更新目标框架后,更新 NuGet 依赖项。 在针对较旧 .NET 版本的包中,可能存在能够利用当前运行时的较新版本。 检查更新,并优先选择适用于你要迁移到的版本的软件包。 某些包可能在较新版本中弃用 API 或更改行为,因此请在更新时查看发行说明。

GitHub Copilot应用现代化

GitHub Copilot现代化代理是用于升级Windows 窗体和WPF应用的建议工具。 它是一种由 AI 提供支持的端到端体验,内置于处理整个升级过程的GitHub Copilot中。

代理遵循三个阶段工作流:

  • 评估。 Copilot检查项目结构、依赖项和代码模式。 它识别破坏性变更、API 兼容性问题、已弃用的模式以及整体升级范围。 然后,它会提供策略决策,例如升级顺序和兼容性处理,供你在继续操作之前进行查看。

  • 规划。 Copilot将评估和确认的选项转换为详细的升级计划、记录升级策略、重构方法、依赖项路径和风险缓解措施。

  • 执行。 Copilot将计划拆分为一系列按顺序执行的任务,并为其设定验证标准,应用代码修复,并逐步提交更改。 如果遇到问题,它无法自动解决,它会请求你的帮助并从更正中吸取教训。

所有升级状态都存储在存储库中 .github/upgrades/ ,因此可以在会话之间暂停和恢复,或者在开发环境之间切换而不丢失进度。

代理支持以下升级路径:

  • .NET Framework(任何版本)至 .NET 8 或更高版本
  • .NET Core 1.x–3.x 到 .NET 8 或更高版本
  • .NET 5-7 到 .NET 8 或更高版本
  • 迁移到 Azure 服务

它可在 Visual Studio 2026、Visual Studio 2022 17.14.16+、Visual Studio Code 和 GitHub CLI 中使用。 若要在 Visual Studio 中启动升级,请在解决方案资源管理器中右键单击解决方案或项目并选择“现代化”,或打开 GitHub Copilot 对话助手 窗口并键入@Modernize。 在Visual Studio Code中,打开 GitHub Copilot 对话助手 面板并键入@modernize-dotnet

有关设置和使用情况的详细信息,请参阅什么是GitHub Copilot现代化?

不可用的 .NET Framework 技术

几个.NET框架技术在.NET中没有等效项,并且需要替代方法,然后应用才能在新运行时上运行。 确定你的应用是否早期依赖于这些技术中的任何一种,因为它们代表了迁移工作最具破坏性的类别。 有关完整参考,请参阅 .NET 上不可用的 .NET Framework 技术

  • 应用程序域

    不支持 AppDomain。 使用 AssemblyLoadContext 进行动态程序集加载,并通过独立的进程或容器实现隔离。 某些 AppDomain API 成员虽然存在,但会在运行时抛出 PlatformNotSupportedException

  • 远程处理

    不支持.NET远程处理。 使用System.IO.PipesMemoryMappedFile用于本地 IPC 或 gRPC 和 ASP.NET Core进行跨计算机通信。 对委托对象调用 BeginInvoke()EndInvoke() 也会引发 PlatformNotSupportedException

  • 代码访问安全性 (CAS)

    CAS 不受支持,不再是安全边界。 改用 OS 级安全边界,例如虚拟化、容器或用户帐户。

  • 安全透明度

    用于将沙盒化代码与安全关键代码分隔开的安全透明机制,不再作为安全边界受支持。 与 CAS 一样,此功能依赖于.NET不提供的运行时强制。 请改用 OS 级隔离机制。

  • Windows Workflow Foundation

    .NET 不支持 WF。 如果应用托管或使用工作流,请考虑 CoreWF,这是面向.NET的 Windows Workflow Foundation 运行时的开源端口。

  • System.EnterpriseServices (COM+)

    不支持 System.EnterpriseServices。 通过 System.EnterpriseServices 使用 COM+ 服务(例如对象池、事务或基于角色的安全性)的应用需要重新设计,以使用替代方案。 对于分布式事务,请考虑使用 System.Transactions。 对于服务托管场景,请考虑使用 ASP.NET Core 或 Worker 服务。

请注意,这些区域中的某些 API 存在于.NET中,但在运行时引发PlatformNotSupportedException,而不是在编译时失败。 在迁移初期就尽早在 .NET 上测试应用,以便在投入完整迁移之前发现这些问题。

开始从 .NET Framework 升级之前

在开始将应用移植到.NET之前,请先完成一组准备步骤,同时项目仍面向 .NET Framework。 先做好这些前期准备工作,可以缩小实际升级期间的变更范围,并让你从一个更清晰、经过验证的基线出发。 有关完整参考,请参阅从 .NET Framework 移植代码的先决条件

  • 升级工具。

    确保你使用的 Visual Studio 版本支持你要面向的 .NET 版本。 较新的 SDK 版本包括改进的迁移支持、更好的分析器和更新的项目模板。 有关 .NET SDK、MSBuild 和Visual Studio版本之间的关系,请参阅.NET SDK、MSBuild 和Visual Studio之间的版本控制关系

  • 目标.NET Framework 4.7.2 或更高版本。

    将项目重定向到移植前.NET Framework 4.7.2 或更高版本。 此版本基于 .NET Standard 2.0 提供最广泛的 API 兼容性,从而减少你在升级过程中会遇到的 API 缺口。

    在Visual Studio中,右键单击项目,选择“属性”,然后将“目标框架”下拉列表更改为.NET Framework 4.7.2。 在继续操作之前重新编译并修复任何问题。

  • 转换为 PackageReference 格式。

    如果项目使用 packages.config 文件来管理 NuGet 引用,请迁移到 PackageReference 格式。 PackageReference 是新式方法,可直接集成到下一步中采用的 SDK 样式项目格式。

    在Visual Studio中,右键单击packages.config解决方案资源管理器并选择“将 packages.config 迁移到 PackageReference”。 在继续操作之前,请查看迁移输出并解决任何警告。

  • 转换为 SDK 样式的项目格式。

    将项目文件切换到 SDK 样式格式。 SDK 风格的项目更简洁,支持多目标框架,并且是 .NET 所必需的。 此转换可以在仍面向.NET框架的同时完成,因此这是一个安全的准备步骤。 许多转换工具会自动处理此问题,也可以通过将项目文件内容替换为 SDK 样式的等效项并重新添加必要的属性来手动转换。

  • 更新 NuGet 依赖项。

    将所有 NuGet 包更新到其最新版本,并首选以 .NET标准 2.0 为目标的包,而不是仅面向 .NET Framework 的包。 这可以降低你更改目标框架时受到依赖项阻碍的风险。 查看软件包的发行说明,确认较新版本中是否引入了任何破坏性更改。

上述所有建议确保在升级到.NET之前,项目处于良好状态。

Windows 兼容性包

从 .NET Framework 移植时最常见的问题之一是缺少 API。 .NET Standard 有意排除无法在所有平台上运行的技术——例如 Windows 注册表、WMI 和 Reflection.Emit——因此默认情况下无法使用这些 API。 Microsoft.Windows.Compatibility NuGet 包填补了该空白。 它在以下技术领域提供约 20,000 个 API:

  • Windows 注册表
  • Windows 事件日志
  • Windows 管理工具 (WMI)
  • Windows 性能计数器
  • 目录服务
  • Windows 访问控制列表 (ACL)
  • Windows 服务
  • Windows 加密
  • Windows Communication Foundation (WCF)
  • 端口、ODBC、CodeDom 等

该包位于标准 2.0 .NET之上,在增量化时特别有用。 它允许先在.NET上生成和运行应用,然后稍后处理更深层次的重构,而无需提前重写特定于Windows的 API 使用情况。

若要将其添加到项目,请安装 Microsoft.Windows.Compatibility NuGet 包:

dotnet add package Microsoft.Windows.Compatibility

有关完整详细信息,请参阅使用 Windows 兼容性包将代码移植到.NET

中断性变更

重大变更是任何升级中意料之中的一部分,无论你是从 .NET Framework 迁移而来,还是在不同的 .NET 版本之间升级。 在开始迁移之前查看它们可防止迁移后期出现意外。 有关完整参考信息,请参阅 在移植代码时的破坏性变更

中断性变更分为多个类别,并非所有都会导致编译时错误:

  • 行为更改 会影响 API 在运行时的工作方式。 签名保持不变,但输出、抛出的异常或内部行为会发生变化。 这类变更最难发现,因为这类变更不会导致构建错误。
  • 二进制兼容性 更改会影响现有编译程序集是否继续工作,而无需重新编译。 删除或更改公共 API 图面会破坏二进制兼容性。
  • 源代码兼容性变更要求你先修改源代码,才能在较新版本下成功编译。
  • 设计时兼容性变更会影响项目在 Visual Studio 或其他设计环境中的打开方式及其行为。

从 .NET Framework 移植时,会跨越较大的版本差距,因此潜在更改列表会更长。 在.NET版本之间进行升级(例如,从 .NET 6 升级到 .NET 9)时,范围更窄,但两者之间的每个版本都可以引入影响应用的更改。 查看你跳过的每个版本的破坏性更改,而不仅仅是目标版本。

特定于Windows 窗体的重大更改记录在从 .NET Framework 迁移到 .NET 的重大更改中。 请根据要升级的版本范围筛选重大变更参考,并查看适用于你的应用所用 API 的相关条目。

升级后的任务

应用在.NET上生成并运行后,请完成一些清理任务,以删除升级中留下的项目。

查看 NuGet 包。

升级过程可能已将包更新到较新版本。 其中一些较新版本会删除旧版本所需的依赖项。 升级后,检查每个更新的包并删除不再需要的任何可传递依赖项。 查看已更新软件包的发布说明,以发现那些不会导致构建错误的行为变化。

清理旧的 NuGet 构件。

如果项目使用 packages.config 文件来管理 NuGet 引用,则迁移到 PackageReference 格式后不再需要该文件。 从项目中删除它。 还可以删除项目或解决方案目录中的本地 packages 文件夹 - NuGet 现在将包存储在用户配置文件中的 .nuget\packages 全局缓存文件夹中。

更新 System.Configuration 引用。

大多数.NET框架应用直接引用System.Configuration。 升级后,你的项目仍可能携带该引用。 库 System.Configurationapp.config 文件中读取运行时配置。 在.NET中,将其替换为 System.Configuration.ConfigurationManager NuGet 包,该包提供不带直接框架程序集引用的相同 API 图面。

升级后实现现代化

应用在.NET上运行后,可以采用.NET Framework 中不可用的新式模式。 无需进行这些更改即可完成升级,但它们可提高可维护性,并利用对.NET的积极投资。 有关更广泛的想法,请参阅从 .NET Framework 升级到.NET后的现代化

从 App.config 迁移到 appsettings.json。

.NET Framework 将 App.config 用于运行时设置,例如连接字符串和日志记录配置。 .NET 应用通常会改用 appsettings.json,由 Microsoft.Extensions.Configuration NuGet 包提供。 许多库(包括日志记录提供程序)已不再支持 App.config,而转为使用 appsettings.json。 迁移使应用与生态系统保持一致,并在添加新依赖项时简化配置。

App.config 文件继续通过 System.Configuration.ConfigurationManager NuGet 包在 .NET 中工作,以便可以增量迁移。 有关指南,请参阅.NET中的配置

将 WebBrowser 控件替换为 WebView2(WPF)。

WebBrowser控件基于不再受支持的Internet Explorer。 .NET的WPF可以改用基于Microsoft Edge的WebView2控件。 WebView2 提供现代、持续维护的浏览器控件,具有更佳的性能、更高的安全性以及对 Web 标准更好的支持。

Microsoft.Web.WebView2 NuGet 包添加到项目。 根据用户运行的Windows版本,他们可能需要单独安装 WebView2 运行时。 有关详细信息,请参阅 Microsoft Edge WebView2 简介