開(kāi)發(fā)技巧:讓.NET應(yīng)用發(fā)布文件夾更清爽!
鏈接:cnblogs.com/lindexi/archive/2021/10/19/15423277.html
前言
大家都知道,在.NET?發(fā)布時(shí),將會(huì)在輸出的 publish 文件夾包含所需的依賴。在?.NET Core 開(kāi)始,引入了 AppHost 的概念,即使是單個(gè)程序集,也需要獨(dú)立的 Exe 可執(zhí)行文件帶上實(shí)際包含 Main 函數(shù)的 dll 文件。
特別是進(jìn)行獨(dú)立發(fā)布的時(shí)候,輸出文件夾上有超級(jí)多個(gè)文件,看起來(lái)不清真。本文來(lái)告訴大家如何使用 PublishFolderCleaner 工具讓發(fā)布文件夾只留一個(gè) Exe 和一個(gè) Lib 文件夾
使用方法
使用方法十分簡(jiǎn)單,只需要安裝?dotnetCampus.PublishFolderCleaner?庫(kù)即可。編輯入口項(xiàng)目的 csproj 文件,添加如下代碼
<ItemGroup>
??<PackageReference?Include="dotnetCampus.PublishFolderCleaner"?Version="3.0.3"?/>
ItemGroup>
接下來(lái)就和之前一樣發(fā)布即可,不影響原有的發(fā)布步驟
效果
發(fā)布完成之后,打開(kāi)發(fā)布文件夾,此時(shí)可以發(fā)現(xiàn)原本亂糟糟的文件夾被替換為只有一個(gè) exe 可執(zhí)行文件和一個(gè) lib 文件夾。雙擊 exe 可執(zhí)行文件即可獲得和之前一樣的效果
打開(kāi) Lib 文件夾,可以看到此文件夾里面就是原本放在發(fā)布文件夾里面的除了入口 exe 之外的其他文件
以上的 PublishFolderCleaner 工具的作用就是將發(fā)布文件夾里面的所有文件,除了入口 exe 之外的文件,都放入到 lib 文件夾里面,然后修改入口 exe 文件的邏輯,讓入口 exe 可以從 lib 文件夾里面讀取入口 dll 文件,從而實(shí)現(xiàn)此功能
例子
我創(chuàng)建了一個(gè)基于 .NET 5 的 WPF 應(yīng)用,給此應(yīng)用加上 dotnetCampus.PublishFolderCleaner 的 NuGet 包
接著使用命令行進(jìn)行發(fā)布,發(fā)布命令如下
dotnet?publish?-r?win-x64?-c?release?--self-contained
接著進(jìn)入到?bin\Release\net5.0-windows\win-x64\publish\?文件夾,可以看到此文件夾只有存放一個(gè) exe 和一個(gè) lib 文件夾,如下
|???WhihuqeabaLeelurlallball.exe
|???
\---lib
????|???clrcompression.dll
????|???clretwrc.dll
????|???clrjit.dll
????|???coreclr.dll
????|???createdump.exe
????|???WhihuqeabaLeelurlallball.deps.json
????|???WhihuqeabaLeelurlallball.dll
????|???WhihuqeabaLeelurlallball.pdb
????|???WhihuqeabaLeelurlallball.runtimeconfig.json
????|???WindowsBase.dll
????|???WindowsFormsIntegration.dll
????|???wpfgfx_cor3.dll
????|???//?忽略很多文件
????+---zh-Hans
????|???????Microsoft.VisualBasic.Forms.resources.dll
????|???????PresentationCore.resources.dll
????|???????//?忽略很多文件
????|???????
????\---zh-Hant
????????????Microsoft.VisualBasic.Forms.resources.dll
????????????//?忽略很多文件
代碼
本文所有代碼放在 github 和 gitee 歡迎訪問(wèn)
可以通過(guò)如下方式獲取本文的源代碼,先創(chuàng)建一個(gè)空文件夾,接著使用命令行 cd 命令進(jìn)入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼
git?init
git?remote?add?origin?https://gitee.com/lindexi/lindexi_gd.git
git?pull?origin?24c0c22f4a0bb292893ac09aba2f14b3b84a2d6e
以上使用的是 gitee 的源,如果 gitee 不能訪問(wèn),請(qǐng)?zhí)鎿Q為 github 的源
git?remote?remove?origin
git?remote?add?origin?https://github.com/lindexi/lindexi_gd.git
獲取代碼之后,進(jìn)入 WhihuqeabaLeelurlallball 文件夾
可以通過(guò)這個(gè)簡(jiǎn)單的例子試試效果
原理
本文使用的 PublishFolderCleaner 工具,在 GitHub 上完全開(kāi)源,屬于我所在團(tuán)隊(duì)構(gòu)建工具鏈的工具,請(qǐng)看 https://github.com/dotnet-campus/dotnetcampus.DotNETBuildSDK
核心機(jī)制就是添加構(gòu)建調(diào)度步驟,在發(fā)布之后執(zhí)行移動(dòng)文件和修改入口 exe 兩個(gè)步驟
其中添加構(gòu)建調(diào)度的邏輯代碼如下
<Project>
??<Target?Name="MoveThePublishFolderToLibFolder"?AfterTargets="Publish">
????<PropertyGroup>
??????<PublishFolderCleanerCommandArgs>dotnet?"$(MSBuildThisFileDirectory)..\tools\net5.0\PublishFolderCleaner.dll"?-p?"$(PublishDir)?"?-a?"$(AssemblyName)"PublishFolderCleanerCommandArgs>
????PropertyGroup>
????<Exec?Command="$(PublishFolderCleanerCommandArgs)">Exec>
??Target>
Project>
也就是在發(fā)布完成之后,通過(guò) dotnet 命令調(diào)用 PublishFolderCleaner 工具,如上面代碼可以看到這是一個(gè) .NET 5 的工具,要求當(dāng)前開(kāi)發(fā)者的開(kāi)發(fā)環(huán)境里面安裝有 .NET 5 才能執(zhí)行此工具
在 PublishFolderCleaner 工具里面完成如上兩個(gè)步驟,將原有的放在發(fā)布文件夾里面的文件全部放入到里層的 lib 文件夾,再通過(guò)修改入口 exe 可執(zhí)行文件,也就是 AppHost 文件,讓入口 exe 從原本的相同文件夾讀取入口 dll 替換為從 lib 文件夾里面讀取入口 dll 文件
關(guān)于修改 AppHost 文件的知識(shí),請(qǐng)參閱 dotnet core 應(yīng)用是如何跑起來(lái)的 通過(guò)AppHost理解運(yùn)行過(guò)程 和 dotnet 桌面端基于 AppHost 的配置式自動(dòng)切換更新后的應(yīng)用程序路徑。
