手把手教會將 Windows 窗體桌面應用從.NET Framework遷移到 .NET SDK/.NET 6 格式

接上篇:手把手教會 VS2022 設計 Winform 高DPI兼容程式 (net461 net6.0 雙出) //www.cnblogs.com/densen2014/p/16142939.html

本文介紹如何將 Windows 窗體桌面應用從 .NET Framework 遷移到 .NET SDK 格式或 .NET 6 或更高版本。 .NET SDK 支援 Windows 窗體應用程式。 Windows 窗體仍是僅適用於 Windows 的框架,並且只能在 Windows 上運行。

將應用從 .NET Framework 遷移到 .NET SDK 格式或 .NET 6 通常需要一個新的項目文件。 NET 6 使用 SDK 樣式的項目文件,而 .NET Framework 通常使用較舊的 Visual Studio 項目文件。 如果你曾經在文本編輯器中打開過 Visual Studio 項目文件,你就會知道它有多麼詳細。 SDK 樣式的項目較小,不需要像舊版項目文件格式那樣多的條目。

備份項目

遷移項目的第一步是備份項目! 如果出現問題,可以通過還原備份將程式碼還原為其原始狀態。 不要依賴於 .NET 可移植性分析器等工具來備份項目,即使它們似乎可以完成備份。 最好是親自創建原始項目的副本。

卸載工程,編輯項目文件

剪切所有內容到記事本.添加空白項目文件

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- 選一種自己需要的方式 -->
    <TargetFramework>net6.0-windows</TargetFramework>
    <TargetFramework>net461</TargetFramework> 
    <TargetFrameworks>net6.0-windows;net461;</TargetFrameworks> 
    <!-- 如果是庫,這句直接刪除,庫不需要定義 <OutputType> 設置-->
    <OutputType>WinExe</OutputType> 
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>
<RootNamespace>FreeRes2019</RootNamespace>
<AssemblyName>FreeRes2019</AssemblyName>

節點

所有的 <PropertyGroup>單獨節點內容 直接全部複製到新項目 <PropertyGroup> 下面

例如

<PropertyGroup>
  <RootNamespace>Freexxx2019</RootNamespace>
  <AssemblyName>Freexxx2019</AssemblyName>
</PropertyGroup>
<PropertyGroup>
  <GenerateManifests>false</GenerateManifests>
</PropertyGroup>

複製到

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- 選一種自己需要的方式 -->
    <TargetFramework>net6.0-windows</TargetFramework>
    <TargetFramework>net461</TargetFramework> 
    <TargetFrameworks>net6.0-windows;net461;</TargetFrameworks> 
    <!-- 如果是庫,這句直接刪除,庫不需要定義 <OutputType> 設置-->
    <OutputType>WinExe</OutputType> 
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <UseWindowsForms>true</UseWindowsForms>
    <!-- 複製到這裡 -->
    <RootNamespace>Freexxx2019</RootNamespace>
    <AssemblyName>Freexxx2019</AssemblyName>
    <GenerateManifests>false</GenerateManifests>
  </PropertyGroup>
</Project>

引用升級

對於這種直接複製到新項目文件即可

    <Content Include="TSCLIB.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>

Reference Include 升級

  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>

新版

<ItemGroup>
    <Import Include="System" />
    <Import Include="System.Core" />
    <Import Include="System.Xml.Linq" />
    <Import Include="System.Data.DataSetExtensions" />
    <Import Include="Microsoft.CSharp" />
    <Import Include="System.Data" />
    <Import Include="System.Net.Http" />
    <Import Include="System.Xml" />
</ItemGroup>

工程引用

刪除 ProjectName節點複製過去

  <ItemGroup>
    <ProjectReference Include="..\AME.FreeRes\AME.FreeRes.csproj">
      <Project>{bd216839-c870-4b5a-b3e3-46bd5f7d8d6d}</Project>
      <Name>AME.FreeRes</Name>
    </ProjectReference>
  </ItemGroup>

複製為

  <ItemGroup>
    <ProjectReference Include="..\AME.FreeRes\AME.FreeRes.csproj" /> 
  </ItemGroup>

Compile 一般不需要複製

  <ItemGroup>
    <Compile Include="Attribute\Attribute.cs" />
    <Compile Include="DataTableBase.cs" />
    ...
</ItemGroup>

NuGet 包

如果項目引用了 NuGet 包,則項目文件夾中可能包含 packages.config 文件。 對於 SDK 樣式的項目,NuGet 包引用是在項目文件中配置的。 Visual Studio 項目文件也可以選擇在項目文件中定義 NuGet 包。 .NET 6 不會將 packages.config 用於 NuGet 包。 在遷移之前,必須將 NuGet 包引用遷移到項目文件中。

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json">
      <Version>13.0.1</Version>
    </PackageReference>
  </ItemGroup>

改為

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json"  Version="13.0.1" />
  </ItemGroup>
要遷移 packages.config 文件,請執行以下步驟:
  1. 在「解決方案資源管理器」中,找到要遷移的項目。
  2. 右鍵單擊「packages.config」>「將 packages.config 遷移到 PackageReference」。
  3. 選擇所有頂級包。
  4. 系統會生成一個生成報告,讓你知道與遷移 NuGet 包有關的任何問題。

庫不需要定義 設置。 如果要升級庫項目,請刪除該條目。

重載項目

將項目轉換為新的 SDK 樣式格式後,請在 Visual Studio 中重載項目:

在「解決方案資源管理器」中,找到要轉換的項目。

右鍵單擊項目,選擇「重載項目」。

如果項目載入失敗,則可能是因為在項目的 XML 中引入了一個錯誤。 打開項目文件以進行編輯,並嘗試識別和修復錯誤。 如果找不到錯誤,請嘗試重啟。

編輯 App.config

如果你的應用包含 app.config 文件,則刪除 元素:

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

對於 App.config 文件,有一些事項需要考慮。 .NET Framework 中的 App.config 文件不僅用於配置應用,還用於配置運行時設置和行為,如日誌記錄。 .NET 6(和 .NET Core)中的 App.config 文件不再用於運行時配置。 如果 App.config 文件包含這些部分,則不會考慮這些部分。

實際項目

升級完成後,遷移的 Windows 窗體項目將類似於以下 XML:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- 選一種自己需要的方式 -->
    <TargetFramework>net6.0-windows</TargetFramework>
    <TargetFramework>net461</TargetFramework> 
    <TargetFrameworks>net6.0-windows;net461;</TargetFrameworks> 
    <!-- 如果是庫,這句直接刪除,庫不需要定義 <OutputType> 設置-->
    <OutputType>WinExe</OutputType> 
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\MatchingGame.Logic\MatchingGame.Logic.csproj" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="MetroFramework" Version="1.2.0.3" />
    <PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.3.261602">
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
  </ItemGroup>
</Project>

我自己的工程,升級項目文件後後,精簡了不少

參考資料

//docs.microsoft.com/zh-cn/dotnet/core/porting/upgrade-assistant-winforms-framework
//docs.microsoft.com/zh-cn/dotnet/desktop/winforms/migration/?view=netdesktop-6.0