Topshelf 是 .NET 建立 Windows 服務的首選庫,但原生不支援 Mono/Linux。GitHub 社群專案 Topshelf.Linux 填補此缺口,讓同一代碼庫在 Windows 跑原生服務,在 Linux 跑 Mono 服務。
Install-Package Topshelf.Linux
class Program {
static void Main(string[] args) {
System.IO.Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));
var host = HostFactory.New(x => {
x.Service<SampleService>(s => {
s.ConstructUsing(() => new SampleService());
s.WhenStarted(v => v.Start());
s.WhenStopped(v => v.Stop());
});
x.UseLinuxIfAvailable(); // ★ 關鍵:啟用 Linux/Mono 支援
x.RunAsLocalSystem();
x.UseLog4Net();
x.SetDescription("SampleService Description");
x.SetDisplayName("SampleService");
x.SetServiceName("SampleService");
});
host.Run();
}
}
UseLinuxIfAvailable 偵測非 Linux,啟動標準 Topshelf ServiceControlManager 主機。Topshelf.Linux.LinuxHost,以主控台應用程式模式運行,支援 start/stop 命令列參數,配合 rc.d/systemd 腳本管理生命週期。| 項目 | 說明 |
|---|---|
| 命令列控制 | Mono 下**不支援** Topshelf 原生 install/uninstall/start/stop 服務命令,需透過系統服務管理器 (systemd/rc.d) 控制。
|
| 服務帳戶 | RunAsLocalSystem 等 Windows 特有設定在 Linux 下會被忽略,以執行使用者身分運行。
|
| 日誌 | 建議統一使用 log4net/NLog 寫入檔案,避免依賴 Windows Event Log。 |
| 相依性 | 確保所有 NuGet 套件支援 .NET Framework 4.x / .NET Standard 2.0,相容 Mono 5.18+。 |
dotnet publish -c Release -r linux-x64 (或 MSBuild 輸出)。/opt/myservice/。/etc/systemd/system/myservice.service:[Unit]
Description=My Topshelf Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/myservice
ExecStart=/usr/bin/mono /opt/myservice/MyService.exe
Restart=on-failure
User=www-data
[Install]
WantedBy=multi-user.target
systemctl daemon-reload && systemctl enable myservice && systemctl start myservice僅需安裝 Topshelf.Linux 並加入 x.UseLinuxIfAvailable(),即可讓既有 Topshelf 服務零成本支援 Mono/Linux 部署,適合漸進式跨平台遷移專案。