1. 程式人生 > >使用.NET Core建立Windows服務(二) - 使用Topshelf方式

使用.NET Core建立Windows服務(二) - 使用Topshelf方式

原文:Creating Windows Services In .NET Core – Part 2 – The “Topshelf” Way
作者:Dotnet Core Tutorials
譯者:Lamond Lu
譯文:使用.NET Core建立Windows服務(二) - 使用Topshelf方式

使用.NET Core建立Windows服務

  • 使用微軟推薦方式
  • 使用Topshelf方式

在前一篇文章中,我給大家介紹了,如何基於微軟推薦方式使用.NET Core建立Windows服務。我們發現使用這種方式,我們很容易就可以搭建和執行一個Windows服務,但是問題是使用這種方式,程式碼除錯將非常困難。

那麼現在就是Topshelf出場的時候了。Topshelf是一個.NET Standard庫,它消除了在.NET Framework和.NET Core中建立Windows服務的那些麻煩。

安裝

與微軟推薦方式類似,這裡Visual Studio並沒有提供一個基於Topshelf建立Windows服務的模板,所以我們依然需要通過建立普通控制檯程式的方式,來建立一個Windows服務。

然後,我們需要通過Package Manager Console, 執行以下命令,安裝Topshelf類庫。

Install-Package Topshelf

程式碼

下面我們就來使用Topshelf重構之前的服務程式碼。

public class LoggingService : ServiceControl
{
    private const string _logFileLocation = @"C:\temp\servicelog.txt";
 
    private void Log(string logMessage)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(_logFileLocation));
        File.AppendAllText(_logFileLocation, 
            DateTime.UtcNow.ToString() + " : " + logMessage + Environment.NewLine);
    }
 
    public bool Start(HostControl hostControl)
    {
        Log("Starting");
        return true;
    }
 
    public bool Stop(HostControl hostControl)
    {
        Log("Stopping");
        return true;
    }
}

程式碼看起來是不是很簡單?

這裡我們的服務類繼承了ServiceControl類(實際上並不需要,但是這可以為我們的工作打下良好的基礎)。我們必須實現服務開始和服務結束兩個方法,並且像以前一樣記錄日誌。

Program.cs檔案的Main方法中,我們要寫的程式碼也非常的簡單。我們可以直接使用HostFactory.Run方法來啟動服務。

static void Main(string[] args)
{
    HostFactory.Run(x => x.Service<LoggingService>());
}

這看起來真是太簡單了。但這並不是HostFactory類的唯一功能。這裡我們還可以設定

  • 服務的名稱
  • 服務是否自動啟動
  • 服務崩潰之後的重啟時間
static void Main(string[] args)
{
    HostFactory.Run(x =>
        {
            x.Service<LoggingService>();
            x.EnableServiceRecovery(r => r.RestartService(TimeSpan.FromSeconds(10)));
            x.SetServiceName("TestService");
            x.StartAutomatically();
         }
    );
}

這裡其實能說的東西很多,但是我建議你還是自己去看看Topshelf的文件,學習一下其他的配置選項。基本上你能使用Windows命令列完成的所有操作,都可以使用程式碼來設定: https://topshelf.readthedocs.io/en/latest/configuration/config_api.html

部署服務

和之前一樣,我們需要針對不同的Windows環境釋出我們的服務。在Windows命令提示符下,我們可以在專案目錄中執行以下命令:

dotnet publish -r win-x64 -c Release

現在我們就可以檢視一下bin\Release\netcoreappX.X\win-x64\publish目錄,我們會發現一個編譯好的exe,下面我們就會使用這個檔案來安裝服務。

在上一篇文章中,我們是使用SC命令來安裝Windows服務的。使用Topshelf我們就不需要這麼做了,Topshelf提供了自己的命令列引數來安裝服務。基本上使用程式碼能完成的配置,都可以使用命令列來完成。

你可以檢視相關的文件:

<http://docs.topshelf-project.com/en/latest/overview/commandline.html>

WindowsServiceExample.exe install

這裡WindowsServiceExample.exe是我釋出之後的exe檔案。執行以上命令之後,服務應該就正常安裝了!這裡有一個小問題,我經常發現,即使配置了服務自動啟動,但是服務安裝之後,並不會觸發啟動操作。所有在服務安裝之後,我們還需要通過以下命令來啟動服務。

WindowsServiceExample.exe start

在生產環境部署的時候,我的經驗是在安裝服務之後,等待10秒鐘,再啟動服務。

除錯服務

當我們是使用微軟推薦方式的時候,我們會遇到了除錯困難的問題。大多數情況下,無論是否在服務內部執行,我們都不得不使用命令列標誌、#IF DEBUG指令或者配置值來實現除錯。然後使用Hack的方式在控制檯程式中模擬服務。

因此,這就是為什麼我們要使用Topshelf

如果我們的服務程式碼已經在Visual Studio中打開了,我們就可以直接啟動除錯。Topshelf會模擬在控制檯中啟動服務。我們應該能在控制檯中看到以下的訊息。

The TestService service is now running, press Control+C to exit.

這確實符合了我們的需求。它啟動了我們的服務,並像真正的Windows服務一樣在後臺執行。我們可以像往常一樣設定斷點,基本上它遵循的流程和正常安裝的服務一樣。

我們可以通過ctrl+c, 來關閉我們的應用,但是在執行服務執行Stop方法之前,它是不能被關閉的,這使我們可以除錯服務的關閉流程。與除錯指令和配置標誌相比,這要容易的多。

這裡需要注意一個問題。如果你收到的以下內容的訊息:

The TestService service is running and must be stopped before running via the console

這意味著你嘗試除錯的服務實際上已經作為Windows服務被安裝在系統中了,你需要停止(不需要解除安裝)這個正在執行的服務,才可以正常除錯。

後續

在上一篇中,有讀者指出.NET Core中實際上已經提供了一種完全不同的方式執行Windows服務。它的實質是利用了ASP.NET Core中引入的“託管服務”模型,並允許它們作為Windows服務來執行,這真的是非常的棒