首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C# 編寫 Windows Service 完整指南:從專案建立到安裝部署

     編輯:更多程式設計知識

核心架構

.NET Framework 封裝了 SCM (Service Control Manager) 互動細節,開發者只需繼承 ServiceBase 並實作生命週期事件。

步驟 1:建立專案與參考

  • 專案類型:Console Application 或 Windows Forms (輸出型別設為 Console Application)
  • 加入參考:System.ServiceProcess.dll, System.Configuration.Install.dll

步驟 2:實作服務類別

using System.ServiceProcess;
using System.Threading;

public class MyService : ServiceBase {
    private Thread _worker;
    private volatile bool _running;

    public MyService() {
        ServiceName = "MyCustomService";
        CanPauseAndContinue = true;
        CanShutdown = true;
    }

    protected override void OnStart(string[] args) {
        _running = true;
        _worker = new Thread(DoWork) { IsBackground = true };
        _worker.Start();
    }

    protected override void OnStop() {
        _running = false;
        _worker?.Join(3000); // 等待優雅退出,最多 3 秒
    }

    protected override void OnPause()  => _running = false;
    protected override void OnContinue() => _running = true;

    private void DoWork() {
        while (_running) {
            // 實際業務邏輯:輪詢資料庫、監控目錄、處理佇列...
            Thread.Sleep(1000);
        }
    }
}

關鍵規則:OnStart/OnStop/OnPause/OnContinue 必須在 30 秒內返回,否則 SCM 判定服務掛起並報錯。耗時操作務必放入背景執行緒。

步驟 3:進入點啟動服務

static class Program {
    static void Main() {
        ServiceBase.Run(new MyService());
    }
}

步驟 4:安裝程式 (Installer)

[RunInstaller(true)]
public class MyServiceInstaller : Installer {
    public MyServiceInstaller() {
        var processInstaller = new ServiceProcessInstaller {
            Account = ServiceAccount.LocalSystem // 或 NetworkService/User
        };
        var serviceInstaller = new ServiceInstaller {
            ServiceName = "MyCustomService",
            DisplayName = "我的自訂服務",
            Description = "示範 C# Windows Service 基本架構",
            StartType = ServiceStartMode.Automatic
        };
        Installers.Add(processInstaller);
        Installers.Add(serviceInstaller);
    }
}

步驟 5:安裝/解除安裝指令

// 開啟 Developer Command Prompt for VS (管理員)
installutil.exe MyService.exe        // 安裝
installutil.exe /u MyService.exe     // 解除安裝
  • 安裝後可在 services.msc 中看到「我的自訂服務」
  • 啟動類型:Automatic (開機自啟) / Manual / Disabled

步驟 6 (可選):客戶端管理工具

服務無 UI,需另建 WinForms/WPF/Console 客戶端,透過以下方式互動:

  • ServiceController:啟動/停止/暫停/狀態查詢
  • 命名管道 / TCP / HTTP API:雙向資料交換
  • EventLog / ETW / 檔案日誌:單向狀態上報

實務避坑清單

  1. 日誌先行:啟動即寫入 EventLog 或 Serilog/NLog,無日誌無法排查
  2. 異常不吞噬:AppDomain.CurrentDomain.UnhandledException + 任務內 try-catch 記錄
  3. 單一實例鎖:Mutex 防止手動雙擊 EXE 造成雙進程
  4. 設定外部化:appsettings.json + IConfiguration,避免重新編譯
  5. 優雅關機:OnStop 發送取消令牌,等待進行中任務完成 (設定逾時)
  6. 權限最小化:能用 NetworkService 別用 LocalSystem

.NET Core / .NET 5+ 現代寫法

// Program.cs
IHost host = Host.CreateDefaultBuilder(args)
    .UseWindowsService() // 自動偵測 SCM
    .ConfigureServices((ctx, svc) => {
        svc.AddHostedService();
    })
    .Build();
host.Run();

// Worker.cs
public class Worker : BackgroundService {
    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        while (!stoppingToken.IsCancellationRequested) {
            // Do work
            await Task.Delay(1000, stoppingToken);
        }
    }
}

新版泛型主機內建 DI、設定、日誌、生命週期管理,強烈建議新專案直接用 .NET 6/8 LTS。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved