一、Windows服務
1、Windows服務應用程序是一種需要長期運行的應用程序,它適合服務器環境。
2、無用戶界面,任何消息都會寫進Windows事件日志。
3、隨計算機啟動而啟動,不需要用戶一定登錄Windows。
4、通過服務控制管理器,可以終止、暫停及當需要時啟動Windows服務。
二、體系結構
System.ServiceProcess命令空間
1、類繼承關系:
- Object
- Component
- ServiceBase
- ServiceController
- Installer
- ComponentInstaller
- ServiceInstaller
- ServiceProcessInstaller
- Component
2、體系結構
第一部分就是服務程序。實現系統的業務需求。
Service Control Manager(SCM)。SCM是操作系統的一個組成部分(services.exe),作用是於服務進行通信。
SCM包含一個儲存着已安裝的服務和驅動程序的信息的數據庫,通過SCM可以統一的、安全的管理這些信息。
一個服務擁有能從SCM收到信號和命令所必需的的特殊代碼,並且能夠在處理后將它的狀態回傳給SCM。
ServiceBase:(服務程序)實現系統的業務需求。 在創建新的服務類時,必須從 ServiceBase 派生。
第二部分服務控制程序,是一個Service Control Dispatcher(SCP)。
它是一個擁有用戶界面,允許用戶開始、停止、暫停、繼續,並且控制一個或多個安裝在計算機上服務的Win32應用程序。
SCP的作用是與SCM通訊,Windows 管理工具中的“服務”就是一個典型的SCP。
ServiceController:(服務控制程序)表示 Windows 服務並允許連接到正在運行或者已停止的服務、對其進行操作或獲取有關它的信息。
第三部分、服務配置程序
配置程序可以安裝服務,向注冊表注冊服務,設置服務的啟動類型、服務的用戶及依存關系等。
ServiceInstaller:(服務安裝配置程序)繼承自Installer類。該類擴展 ServiceBase 來實現服務。 在安裝服務應用程序時由安裝實用工具調用該類。
ServiceProcessInstaller :(服務安裝配置程序)繼承自Installer類。安裝一個可執行文件,該文件包含擴展 ServiceBase 的類。 該類由安裝實用工具(如 InstallUtil.exe)在安裝服務應用程序時調用。
三、創建Windows服務:ServiceBase
新建一個“Windows服務”項目,添加一個System.Timers.Timer組件。
1)單個服務
static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new MyService1() }; ServiceBase.Run(ServicesToRun); }
服務程序:
public partial class MyService1 : ServiceBase { public MyService1() { InitializeComponent();
myTimer = new System.Timers.Timer();
myTimer.Interval = 60000; //設置計時器事件間隔執行時間
myTimer.Elapsed += (timer1_Elapsed);
this.ServiceName = "我的服務"; this.AutoLog = true;//是否自行寫入系統的事件日志 this.CanHandlePowerEvent = true;//是否接受電源事件 this.CanPauseAndContinue = true;//是否能暫停或繼續 this.CanShutdown = true;//是否在計算機關閉時收到通知 this.CanStop = true;//是否接受停止運行的請求 } private void timer1_Elapsed(object sender, ElapsedEventArgs e) { File.AppendAllText("C:\\1.txt", "Service Runing"); } string filePath = @"D:\MyServiceLog.txt"; protected override void OnStart(string[] args) { this.timer1.Enabled = true; File.AppendAllText("C:\\1.txt", "Service Started"); } protected override void OnStop() { this.timer1.Enabled = false; File.AppendAllText("C:\\1.txt", "Service Stoped"); } }
服務在運行時,獲取其可執行文件的父目錄:
AppDomain.CurrentDomain.BaseDirectory;
2)多個服務
static void Main() { ServiceBase[] ServicesToRun; string Line = Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory).Name; DCWinService lineService = new DCWinService(Line); lineService.ServiceName = "GPE.PAMSDC.DCService(" + Line + ")"; ServicesToRun = new ServiceBase[] { lineService }; ServiceBase.Run(ServicesToRun); }
public partial class DCWinService : ServiceBase { public DCWinService() { InitializeComponent(); } string line; public DCWinService(string line) { this.line = line; } protected override void OnStart(string[] args) { // TODO: 在此處添加代碼以啟動服務。 GPE.PAMSDC.DCServer.Start(line);//動態加載 } protected override void OnStop() { // TODO: 在此處添加代碼以執行停止服務所需的關閉操作。 GPE.PAMSDC.DCServer.Stop(line); } } }
四、添加服務安裝程序:(與服務程序同一項目)
配置設置。

1)單個服務:
// serviceInstaller1 this.serviceInstaller1.Description = "消息發送服務."; this.serviceInstaller1.DisplayName = "MyService1"; this.serviceInstaller1.ServiceName = "MyService1";//要與前面的定義的服務名一致。 this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic; // serviceProcessInstaller1 this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; this.serviceProcessInstaller1.Password = null; this.serviceProcessInstaller1.Username = null; // DCServiceInstaller this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.serviceInstaller1, this.serviceProcessInstaller1});
2)多個服務:
string[] lines = new string[] { "T1", "T2" }; ServiceInstaller serviceInstaller1; foreach (string line in lines) { // serviceInstaller1 serviceInstaller1 = new ServiceInstaller(); serviceInstaller1.Description = "消息發送服務."; serviceInstaller1.DisplayName = "GPE.PAMSDC.DCService(" + line + ")"; serviceInstaller1.ServiceName = "GPE.PAMSDC.DCService(" + line + ")"; this.Installer.Add(this.serviceInstaller1);//serviceInstaller可以有多個 } // serviceProcessInstaller1 this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; // DCServiceInstaller this.Installers.Add(this.serviceProcessInstaller1);//serviceProcessInstaller只能有一個
注意:在服務安裝程序中,獲取可執行文件的父目錄:Directory.CreateDirectory("./").Name
五、Windows服務的安裝程序
1、創建一個“安裝部署”的項目,右鍵項目名稱,選擇“添加”-“項目輸出”,選擇前面創建的服務項目,再選擇“主輸出”。也可以右擊安裝項目,“視圖”,“添加自定義操作”。
2、使用InstallUtil.exe工具,批處理文件為:
- 安裝:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe ./GPE.PAMSDC.DCService.exe
Net Start DCService
sc config DCServicestart= auto
- 卸載:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe -u ./GPE.PAMSDC.DCService.exe
通過第三方組件 (Topshelf)創建C# Windows服務應用程序。
六、服務控制程序:ServiceController
List<ServiceController> services = new List<ServiceController>(ServiceController.GetServices()); services = services.FindAll(s => s.DisplayName.StartsWith("GPE.PAMSDC.DCService")); services.Sort((s1, s2) => s1.DisplayName.CompareTo(s2.DisplayName)); List<ServiceControllerInfo> serviceInfo = services.ConvertAll(s => new ServiceControllerInfo(s)); foreach (ServiceControllerInfo si in serviceInfo) { if (si.EnableStart) { si.Controller.Start(); si.Controller.WaitForStatus(ServiceControllerStatus.Running); } }
七、調試Windows服務
必須首先啟動服務,然后將一個調試器附加到正在運行的服務的進程中。
1、用VS加載這個服務項目。
2、“調試”菜單,“附加到進程”。
3、確保“顯示所有用戶進行”被選擇。
4、在“可用進程”列表中,選中你的可執行文件的名稱。
5、點擊“附加”按鈕。
6、在timer_Elapsed方法中設置斷點,然后執行,從而實現調試的目的。