我們知道 .NET Core 應用程式有兩種部署方式,一種叫 FDD (框架相依的部署),另一種叫 SCD (自封式部署)。當使用 SCD 部署的時候,可以直接指定平台(RID)進行封裝,不過缺點是檔案數量與檔案大小都非常驚人,唯一的好處就是目的電腦不用安裝 .NET Core Runtime 就能執行程式。本篇文章我將介紹一套用 Rust 程式語言寫成的 Warp 工具,幫助你將檔案封裝成單一執行檔。
架構介紹
Warp 是一套跨平台工具,其中包含兩個主程式:warp-runner
與 warp-packer
。其中 warp-packer
用來將現有的 Node.js 或 .NET Core 應用程式封裝成單一執行檔,而 warp-runner
則是內建在這個由 warp-packer
建立的單一執行檔內,用來執行你的主程式。
簡單來說,warp-packer
是一支工具程式,它會將你要部署的所有檔案壓縮起來,包含主程式與所有相依的檔案,然後連同 warp-runner
一起封裝到一個單一可執行檔中。當要執行這支單一可執行檔的時候,warp-runner
會先將所有檔案解壓縮,放置到本機快取資料夾中,然後自動找到主程式來執行。
本機快取資料夾在不同平台的路徑分別是:
- Linux:
$HOME/.local/share/warp/packages
- macOS:
$HOME/Library/Application Support/warp/packges
- Windows:
%LOCALAPPDATA%\warp\packages
基於這個架構,其實不只有 Node.js 或 .NET Core 可以拿來封裝,就連 Java、Python 都可以用這套工具來封裝應用程式。
將 .NET Core 透過 SCD 部署的程式打包成可在 Windows 執行的單一執行檔
建立專案並使用 SCD 發行:
dotnet new console -n c1
cd c1
dotnet publish -c Release -r win10-x64
預設發行的路徑會在:bin\Release\netcoreapp2.2\win10-x64\publish\
接著下載 warp-packer.exe
工具,用來將發行的檔案封裝成單一可執行檔:
-
PowerShell 命令
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"; Invoke-WebRequest https://github.com/dgiagio/warp/releases/download/v0.3.0/windows-x64.warp-packer.exe -OutFile warp-packer.exe
-
命令提示字元 (Cmd)
powershell -Command "[Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11, tls'; Invoke-WebRequest https://github.com/dgiagio/warp/releases/download/v0.3.0/windows-x64.warp-packer.exe -OutFile warp-packer.exe
然後透過 warp-packer.exe
工具產生單一執行檔:
.\warp-packer --arch windows-x64 --input_dir bin\Release\netcoreapp2.2\win10-x64\publish\ --exec c1.exe --output c1.exe
最後,在當前目錄下就會看到一個新的 c1.exe
執行檔,這個檔案由於有壓縮過,所以會比 SCD 封裝的檔案還小一點。接著直接執行它:
c1.exe
第一次執行的時候由於要先解壓縮,所以執行時間會久一些。不過第一次執行完之後,速度就跟直接執行 .NET Core 沒甚麼兩樣,因為所有檔案已經解壓縮到本機快取資料夾下!
在 Linux 或 macOS 封裝用 SCD 部署的 .NET Core 應用程式
其實在 Warp 網站都有詳述這套工具在不同平台的使用方式,使用方是完全一樣,不外乎三個步驟:
- 下載
- 封裝 ( 在
--arch
參數要設定 linux-x64
或 macos-x64
架構 )
- 執行
warp-packer 0.3.0
Diego Giagio <diego@giagio.com>
Create self-contained single binary application
USAGE:
warp-packer.exe --arch <arch> --exec <exec> --input_dir <input_dir> --output <output>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-a, --arch <arch> Sets the architecture.
Supported: ["windows-x64", "linux-x64", "macos-x64"]
-i, --input_dir <input_dir> Sets the input directory containing the application and dependencies
-e, --exec <exec> Sets the application executable file name
-o, --output <output> Sets the resulting self-contained application file name
未來展望
這套工具其實不是理想的解決方案,真正理想的解決方案應該是微軟官方的 CoreRT 才對。
CoreRT 是一套全新的 .NET Core 執行環境,專門用來實現 .NET Core 的 AOT (ahead of time compilation) 編譯,讓編譯出來的檔案可以直接原生執行在不同平台。
不過目前 CoreRT 還在 Alpha 階段,還不建議在生產環境使用,但非常值得期待。我實際測試過,一個 .NET Core 專案透過 SCD 發行,需要部署的檔案數量有 217 個,檔案總大小為 66.1MB 左右。但若改用 CoreRT 進行 AOT 編譯,只會產生一個 *.exe
與一個 *.pdb
檔,該執行檔則只有 3.7MB 而已,而且程式的啟動速度極快,相當驚人!
相關連結