TopShelf 讓你輕鬆的做 Windows Service

Posted by Ryan Tseng on 2018-10-25

以往我們都是透過 Windows Service 的專案來包裝 Windows Service,但這篇要介紹怎麼樣使用 TopShelf 框架,讓我們可以很簡便的使用 TopShelf 包裝好的功能進行 安裝移除 等等的操作,讓我們可以更專心的處理實際運行的商業邏輯。

環境

  • Windows 10
  • .NET Framework 4.7.1
  • Rider 2018.2.3

專案準備

  • Console Application
  • nuget install TopShelf

可執行的範例

  • Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var svc = HostFactory.Run(x =>
{
x.Service<ServiceWrapper>(s =>
{
s.ConstructUsing(g => new ServiceWrapper());
s.WhenStarted(g => g.Start());
s.WhenStopped(g => g.Stop());
});


x.RunAsLocalSystem();

x.SetDisplayName("Sample");
x.SetServiceName("Sample");
x.SetInstanceName("Demo");
x.SetDescription("Sample Service");
});
  • ServiceWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ServiceWrapper
{

public ServiceWrapper()
{
Console.WriteLine("=== Constructor ===");
}

public void Start()
{
Console.WriteLine("=== Service Start ===");
}

public void Stop()
{
Console.WriteLine("=== Service Stop ===");
}
}

設定參數

  • 顯示名稱相關設定
    • Service Name 服務名稱
    • Service Description 服務描述
    • Display Name 顯示名稱
    • Instance Name 實體名稱

設定和 Windows 服務的設定視窗基本上是互相對應的,如下圖

  • Service 相關設定
    • StartMode 啟動類型
      • x.StartAutomatically(); 自動啟動
      • x.StartAutomaticallyDelayed(); 自動啟動並且延遲 (.NET 4.0 later)
      • x.StartManually(); 手動啟動
      • x.Disabled(); 安裝 已停用 的 service
    • Service 復原
      • c.RestartComputer(5, "message"); 等多少分鐘後重啟電腦
      • c.RestartService(0); 等多少分鐘後重啟服務
      • c.RunProgram(7, "ping google.com"); 等多少分鐘後執行 Command
      • c.OnCrashOnly(); 當使用這個設定時,只有 exit code 為 0 的時候才會重啟
      • c.SetResetPeriod(1); 重啟的區間(以天為單位)
    • 自訂安裝動作 (類似 Hooks)
      • x.BeforeInstall(settings => { ... })
      • x.AfterInstall(settings => { ... })
      • x.BeforeUninstall(settings => { ... })
      • x.AfterUninstall(settings => { ... })
    • Service 的相依性
      • x.DependsOn("SomeOtherService")
      • 內建的 Extensions
        • x.DependsOnMsmq();
        • x.DependsOnMsSql();
        • x.DependsOnEventLog();
        • x.DependsOnIis();
    • 進階設定
      • x.EnablePauseAndContinue();
      • x.EnableShutdown();
      • x.OnException(ex => { ... })

還有其它細部設定可以到官方文件上參考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
HostFactory.New(x => {

// StartMode Configuration
x.StartAutomatically();
x.StartAutomaticallyDelayed();
x.StartManually();
x.Disabled();

// Recovery Configuration
x.EnableServiceRecovery(c =>
{
c.RestartComputer(5, "hello");
c.RestartService(0);
c.RunProgram(7, "ping www.google.com");
c.OnCrashOnly();
c.SetResetPeriod(1);
});

// Custom Install Actions
x.BeforeInstall(settings => { ... })
x.AfterInstall(settings => { ... })
x.BeforeUninstall(settings => { ... })
x.AfterUninstall(settings => { ... })

// Service Dependency
x.DependsOn("SomeService");

// Built-in Extensions
x.DependsOnMsmq();
x.DependsOnMsSql();
x.DependsOnEventLog();
x.DependsOnIis();

});

偵錯

偵錯這個部分在 TopShelf 上面算是相對容易的,如果直接透過 IDE 執行起來的話,他就跟一般的 Console Application 無異,能夠直接透過 IDE 來 Debug

安裝 Service

解除安裝 Service

其他的指令可以透過 help 來進行查詢 (如下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Command-Line Reference
service.exe [verb] [-option:value] [-switch]
run Runs the service from the command line (default)
help, --help Displays help
install Installs the service
--autostart The service should start automatically (default)
--disabled The service should be set to disabled
--manual The service should be started manually
--delayed The service should start automatically (delayed)
-instance An instance name if registering the service
multiple times
-username The username to run the service
-password The password for the specified username
--localsystem Run the service with the local system account
--localservice Run the service with the local service account
--networkservice Run the service with the network service permission
--interactive The service will prompt the user at installation for
the service credentials
start Start the service after it has been installed
--sudo Prompts for UAC if running on Vista/W7/2008
-servicename The name that the service should use when
installing
-description The service description the service should use when
installing
-displayname The display name the the service should use when
installing
start Starts the service if it is not already running
stop Stops the service if it is running
uninstall Uninstalls the service
-instance An instance name if registering the service
multiple times
--sudo Prompts for UAC if running on Vista/W7/2008

參考資料