<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
</Project>
嵌入的资源会自动包含在内,但资源不会,因此需要将资源迁移到新的项目文件。
通过“将 packages.config 迁移到 PackageReference”选项,可轻松地将外部包引用移至前面提到的新格式。
更新包引用
如前一部分中所示,更新发现的兼容包版本。
修复代码和生成
Microsoft.Windows.Compatibility
如果应用程序依赖于 .NET 上不可用的 API(如注册表或 ACL),则必须包含对 Microsoft.Windows.Compatibility
包的引用以添加这些特定于 Windows 的 API。 它们可在 .NET 上工作,但由于它们无法跨平台,因此未包含在内。
有一个名为“平台兼容性分析器”(https://learn.microsoft.com/dotnet/standard/analyzers/platform-compat-analyzer) 的工具,可帮助你识别与你的代码不兼容的 API。
使用 #if 指令
如果在以 .NET Framework 和 .NET 为目标时需要不同的执行路径,则应使用编译常量。 向代码中添加一些 #if 指令,为这两个目标保留相同的代码库。
.NET 上不可用的技术
某些技术在 .NET 上不可用,例如:
AppDomain
代码访问安全性
Windows 工作流
因此,如果在应用程序中使用这些技术,则需要寻找这些技术的替代技术。 有关详细信息,请参阅文章在 .NET Core 和 .NET 5+ 上不可用的 .NET Framework 技术。
重新生成自动生成的客户端
如果应用程序使用自动生成的代码(例如 WCF 客户端),则可能需要重新生成此代码,从而以 .NET 为目标。 有时,你可以找到某些缺少的引用,因为它们可能不包含在一组默认的 .NET 程序集中。 使用 https://apisof.net/ 等工具,可轻松地找到缺少的引用所在的程序集,并从 NuGet 添加该引用。
回滚包版本
一般情况下,我们之前已提到过,你最好更新每个单独的包版本,使其与 .NET 兼容。 然而,你会发现以一个程序集的更新版本和兼容版本为目标是不值得的。 如果更改的成本不可接受,可考虑回滚包版本,保留你在 .NET Framework 上使用的版本。 尽管它们可能不以 .NET 为目标,但它们应该能够正常工作,除非它们调用了某些不受支持的 API。
运行和测试
若应用程序生成无错误,便可通过测试每个功能开始迁移的最后一步。
在最后一步中,你会发现一些不同的问题,具体取决于应用程序的复杂性以及使用的依赖项和 API。
例如,如果你使用配置文件 (app.config),则可能会在运行时发现一些错误,如“配置节”不存在。 使用 Microsoft.Extensions.Configuration
NuGet 包应可修复该错误。
出现错误的另一个原因是使用了 BeginInvoke
和 EndInvoke
方法,因为它们在 .NET 上不受支持。 .NET 不支持它们,因为它们依赖于远程处理,而远程处理 .NET 上并不存在。 若要解决此问题,请尝试使用 await
关键字(如可用)或 Task.Run 方法。
可使用兼容性分析器,识别代码中可能会在 .NET 中运行时引发问题的 API 和代码模式。 转到 https://github.com/dotnet/platform-compat,对你的项目使用 .NET API 分析器。
为了展示 Windows 窗体应用程序的完整迁移过程,我们选择迁移 https://github.com/dotnet-architecture/eShopModernizing/tree/master/eShopLegacyNTier/src/eShopWinForms 处提供的 eShop 示例应用程序。 可在 https://github.com/dotnet-architecture/eShopModernizing/tree/master/eShopModernizedNTier/src/eShopWinForms 处找到迁移的完整结果。
此应用程序显示一个产品目录,并允许用户导航、筛选和搜索产品。 从体系结构的角度来看,该应用依赖于充当后端数据库外观的外部 WCF 服务。
下图中显示了主应用程序窗口:
如果你打开 .csproj 项目文件,则可看到如下所示的内容:
如前所述,.NET 项目的样式更精简,你需要将项目结构迁移到新的 .NET SDK 样式。
在解决方案资源管理器中,右键单击该 Windows 窗体项目,然后选择“卸载项目”>“编辑”。
现在,可更新该 .csproj 文件。 你将删除整个内容,并将其替换为以下代码:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
</Project>
保存并重载该项目。 你现在已经完成了项目文件的更新,并且该项目面向 .NET 7。
如果此时编译项目,你会发现一些与 WCF 客户端引用相关的错误。 由于此代码是自动生成的,因此必须重新生成它,使其以 .NET 为目标。
删除 Reference.cs 文件并生成新的服务客户端。
右键单击“连接的服务”,然后选择“添加连接的服务”选项 。
“连接的服务”窗口随即打开。 选择“Microsoft WCF Web 服务”选项。
如果你在与本示例相同的解决方案中有 WCF 服务,则可选择“发现”选项,而不是指定服务 URL。
找到该服务后,该工具将反映该服务实现的 API 协定。 将命名空间的名称更改为 eShopServiceReference
,如下图所示:
选择“完成”按钮。 一段时间后,你将看到生成的代码。
应会显示三个自动生成的文件:
Getting Started:一个指向 GitHub 的链接,提供某些有关 WCF 的信息。
ConnectedService.json:用于连接到服务的配置参数。
Reference.cs:实际 WCF 客户端代码。
如果再次编译,你会看到许多来自 Helper 文件夹内的 .cs 文件的错误 。 此文件夹存在于 .NET Framework 版本中,但不包含在旧 .csproj 中。 但对于新的 SDK 样式项目,默认包括项目文件位置下存在的每个代码文件。 也就是说,新的 .NET Core 项目会尝试编译 Helper 文件夹内的文件。 由于不需要该文件夹,因此你可安全地将其删除。
如果再次编译该项目并执行它,你将看不到产品图像。 问题在于,文件的路径现在略有变化。 若要解决此问题,需要在路径中添加添加另一个深度级别,更新文件 CatalogView.cs
中的以下行:
string image_name = Environment.CurrentDirectory + "\\..\\..\\Assets\\Images\\Catalog\\" + catalogItems.Picturefilename;
string image_name = Environment.CurrentDirectory + "\\..\\..\\..\\Assets\\Images\\Catalog\\" + catalogItems.Picturefilename;
在此更改后,可检查该应用程序是否在 .NET 7 上按预期启动并运行。
迁移 WPF 应用程序
使用 Shop.ClassicWPF
示例应用程序来执行迁移。 下图显示了迁移之前的应用的屏幕截图:
此应用程序使用本地 SQL Server Express 数据库来保存产品目录信息。 可直接从 WPF 应用程序访问此数据库。
首先,必须将 .csproj 文件更新为 .NET Core 应用程序使用的新 SDK 样式。 按照 Windows 窗体迁移中所述的相同步骤进行操作:卸载项目、打开 .csproj 文件、更新其内容并重载该项目。
在本例中,请删除 .csproj 文件的所有内容,并将其替换为以下代码:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<UseWpf>true</UseWpf>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
</Project>
如果重载并编译该项目,你会收到以下错误:
由于已删除所有 .csproj 内容,因此你丢失了旧项目中的项目引用规范。 只需将此行添加到 .csproj 文件,即可再次包含该项目引用:
<ItemGroup>
<ProjectReference Include="..\\eShop.SqlProvider\\eShop.SqlProvider.csproj" />
<ItemGroup>
你也可通过右键单击“依赖项”节点并选择“添加项目引用”,让 Visual Studio 为你提供帮助 。 从解决方案中选择该项目,然后选择“确定”:
添加缺少的项目引用后,应用程序将在 .NET 上按预期方式编译和运行。
上一页下一页