PublishFolderCleaner 讓你的 dotnet 應用釋出資料夾更加整潔

lindexi 發表於 2021-10-19

大家都知道,在 dotnet 釋出時,將會在輸出的 publish 資料夾包含所需的依賴。在 .NET Core 開始,引入了 AppHost 的概念,即使是單個程式集,也需要獨立的 Exe 可執行檔案帶上實際包含 Main 函式的 dll 檔案。特別是進行獨立釋出的時候,輸出資料夾上有超級多個檔案,看起來不清真。本文來告訴大家如何使用 PublishFolderCleaner 工具讓釋出資料夾只留一個 Exe 和一個 Lib 資料夾

使用方法

使用方法十分簡單,只需要安裝 dotnetCampus.PublishFolderCleaner 庫即可。編輯入口專案的 csproj 檔案,新增如下程式碼

  <ItemGroup>
    <PackageReference Include="dotnetCampus.PublishFolderCleaner" Version="3.0.3" />
  </ItemGroup>

接下來就和之前一樣釋出即可,不影響原有的釋出步驟

效果

釋出完成之後,開啟發布資料夾,此時可以發現原本亂糟糟的資料夾被替換為只有一個 exe 可執行檔案和一個 lib 資料夾。雙擊 exe 可執行檔案即可獲得和之前一樣的效果

開啟 Lib 資料夾,可以看到此資料夾裡面就是原本放在釋出資料夾裡面的除了入口 exe 之外的其他檔案

以上的 PublishFolderCleaner 工具的作用就是將釋出資料夾裡面的所有檔案,除了入口 exe 之外的檔案,都放入到 lib 資料夾裡面,然後修改入口 exe 檔案的邏輯,讓入口 exe 可以從 lib 資料夾裡面讀取入口 dll 檔案,從而實現此功能

例子

我建立了一個基於 .NET 5 的 WPF 應用,給此應用加上 dotnetCampus.PublishFolderCleaner 的 NuGet 包

接著使用命令列進行釋出,釋出命令如下

dotnet publish -r win-x64 -c release --self-contained

接著進入到 bin\Release\net5.0-windows\win-x64\publish\ 資料夾,可以看到此資料夾只有存放一個 exe 和一個 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
            // 忽略很多檔案

程式碼

本文所有程式碼放在 githubgitee 歡迎訪問

可以通過如下方式獲取本文的原始碼,先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 24c0c22f4a0bb292893ac09aba2f14b3b84a2d6e

以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

獲取程式碼之後,進入 WhihuqeabaLeelurlallball 資料夾

可以通過這個簡單的例子試試效果

原理

本文使用的 PublishFolderCleaner 工具,在 GitHub 上完全開源,屬於我所在團隊構建工具鏈的工具,請看 https://github.com/dotnet-campus/dotnetcampus.DotNETBuildSDK

核心機制就是新增構建排程步驟,在釋出之後執行移動檔案和修改入口 exe 兩個步驟

其中新增構建排程的邏輯程式碼如下

<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>

也就是在釋出完成之後,通過 dotnet 命令呼叫 PublishFolderCleaner 工具,如上面程式碼可以看到這是一個 .NET 5 的工具,要求當前開發者的開發環境裡面安裝有 .NET 5 才能執行此工具

在 PublishFolderCleaner 工具裡面完成如上兩個步驟,將原有的放在釋出資料夾裡面的檔案全部放入到裡層的 lib 資料夾,再通過修改入口 exe 可執行檔案,也就是 AppHost 檔案,讓入口 exe 從原本的相同資料夾讀取入口 dll 替換為從 lib 資料夾裡面讀取入口 dll 檔案

關於修改 AppHost 檔案的知識,請參閱 dotnet core 應用是如何跑起來的 通過AppHost理解執行過程dotnet 桌面端基於 AppHost 的配置式自動切換更新後的應用程式路徑

相關文章