在VisualStudio中建立NetCore以上版本的專案,使用的都是新版本風格的專案檔案。
和舊版本.NetFramework版本的專案檔案區別:
- 雙擊專案可直接開啟csproj檔案進行編輯配置
- 專案檔案內容的改變
- 專案屬性資料夾圖示更改
- 專案
引用
去除,改成依賴項
- Nuget包引用區別
- 新版C#語法支援
- 多目標框架版本支援
- ...
其中最大的區別可以說是引用的改變,
在舊版本的專案檔案中,專案所有的引用(dll/nuget/com/專案)全部糅雜在一起(後續有個版本會用圖示區別nuget,但是有bug),對人來說很不友好。
並且nuget包的引用全部儲存在專案的packages.config檔案中,但是包還原時卻是還原在解決方案檔案(sln)同目錄的packages目錄下,導致大型專案有多個解決方案同時引用一個專案時導致包路徑錯誤的問題。
對比如圖,很明顯,新版本的專案檔案依賴項更加簡潔明瞭。
並且除了依賴項,如果你用記事本開啟過.csproj檔案,你會發現.NetFramework版本的專案檔案內容非常多,他把整個專案的檔案引用都記錄在其中,並且還有大量MSBuild相關的編譯配置等。
但是在新版風格(NetCore)的專案檔案中,大大減少,檔案預設使用檔案系統引用,不再顯示記錄在csproj檔案中,這樣可以解決以前增刪了程式碼檔案而沒提交專案檔案導致的編譯錯誤,並且使得專案檔案可以很容易的手動修改各種配置。
各種優點都說完了,但是很多人會疑問,這是NetCore風格的專案檔案,並不是所有.NetFramework的專案都可以升級為Core,無須擔心,即使是.NetFramework也可以使用新版的專案檔案,只需要安裝了NetCore或者更高版本的SDK就行,最後編譯出來的程式集並不需要依賴NetCore的Runtime。
並且新版本的專案檔案支援多目標框架版本,一個專案即可編譯出多個目標框架版本的程式集,
如何遷移
如果是簡單的專案,沒有各種騷操作,直接新建一個NetCore的專案,把csproj檔案替換即可
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net40</TargetFramework>
<ApplicationIcon />
<StartupObject />
<!-- <UseWPF>true</UseWPF> -->
<!-- <UseWindowsForms>true</UseWindowsForms> -->
</PropertyGroup>
</Project>
之前見過有人開發了自動遷移工具,但是沒儲存收藏,現在找不到了
下面是一些升級遇到過的問題
1. AssemblyInfo.cs檔案衝突
注意預設的AssemblyInfo檔案需要刪除,因為新的專案檔案會隱式生成程式集資訊,如果需要顯示指定,需要配置GenerateAssemblyInfo
為false
,並且需要使用版本萬用字元的話還需要配置Deterministic
為false
。
2. Nuget引用方式
nuget引用需要從package.config遷移到專案檔案的PackageReference
節點。
2. 生成路徑帶有版本框架的資料夾
.NetFramework的專案預設生成路徑為bin/Debug
,但是Core之後會再加一層框架版本資料夾,這是因為新版本的專案檔案支援多目標框架版本,如果不需要這層資料夾只要修改AppendTargetFrameworkToOutputPath
配置為false
即可。
3. 使用多版本目標框架
NetCore風格的專案檔案支援多目標框架版本,就是一個專案可以生成多個目標框架版本的程式集,而不需要建立多個專案,該功能只需要把原本的TargetFramework
節點修改成TargetFrameworks
就行,使用分號分隔框架版本,例如<TargetFrameworks>net40;netcoreapp2.1;netcoreapp3.1;net5.0;net5.0-windows</TargetFrameworks>
。
4. 專案構建時自動生成nuget包
NetCore風格的專案檔案只需配置好包資訊,可以在每次構建時自動生成Nuget包,並且會根據專案依賴自動生成包依賴,無須手動編寫nuspec檔案,更多配置可參考官方文件。也可參照我的例項
<!--自動生成Nuget包-->
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!--生成專案Xml文件(包)-->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!--除錯符號檔案嵌入到dll中,以便附加除錯nuget包程式(專案生成nuget包預設不含pdb檔案,想要除錯需要用符號包或者下面方式)-->
<!-- https://docs.microsoft.com/zh-cn/dotnet/core/deploying/single-file#include-pdb-files-inside-the-bundle -->
<!-- https://docs.microsoft.com/zh-cn/nuget/create-packages/symbol-packages-snupkg -->
<DebugType>embedded</DebugType>
<!--包資訊-->
<PackageIcon>Logo.png</PackageIcon>
<Authors>XXXX</Authors>
<Company>XXXX</Company>
<Description>XXXX</Description>
<!--包版本-->
<Version Condition="'$(Configuration)' == 'Debug'">0.1.5-$(Time)</Version>
<Version Condition="'$(Configuration)' == 'Release'">0.1.5</Version>
5. 無法用命令dotnet build
編譯帶資原始檔的專案
如果是Winform或在WPF專案,大概率會有資原始檔,如果使用vs功能選單生成則沒有此問題,但是使用dotent cli進行編譯則會出現以下錯誤,但是這是NetCore專案才會出現的問題和處理方式,目前暫時不知道有什麼解決方法,由於沒有CI/CD的需求,也就沒有過多深究了。
C:\Program Files\dotnet\sdk\5.0.400\Microsoft.Common.CurrentVersion.targets(3162,5): error MSB3823: 非字串資源要求將屬性 GenerateResourceUsePreserializedResources 設定為 true。 [E:\xxxx.csproj]
C:\Program Files\dotnet\sdk\5.0.400\Microsoft.Common.CurrentVersion.targets(3162,5): error MSB3822: 非字串資源要求在執行時使用 System.Resources.Extensions 程式集,但未在此專案的引用中找到它。 [E:\xxxx.csproj]
6. 低版本框架使用高版本C#語法
.NetFramework的專案最高只能支援C#7.3(貌似?不太記得了),許多C#8/C#9以及即將釋出的C#10的新特性無法使用,升級後如果不指定會預設支援框架版本相容的C#版本,但是可以手動配置專案專案的LangVersion
指定使用相應版本的C#。除了一些需要框架支援的新特性,大部分語法特性都可以支援。例如單行using,switch表示式,頂級語句,init關鍵字,匹配模式,解構表示式,ref加強等等。
暫時只想起這些,後續會持續更新
。。。。。。。。。。。。。。。。。
參考文件
修改.csproj檔案_從.NET Core將現有.NET專案檔案升級為精益的新CSPROJ格式
.net core 選擇檔案_.net core遷移實踐:專案檔案csproj的轉換