C#創(chuàng)建控制Windows服務(wù)
需求
針對(duì)一種特殊的應(yīng)用, 不需要顯示GUI, 希望常駐在Windows服務(wù)當(dāng)中,在必要的時(shí)候我們可以進(jìn)行啟動(dòng)或開機(jī)啟動(dòng)。
這個(gè)時(shí)候我們就可以創(chuàng)建WindowsService 來(lái)實(shí)現(xiàn)。
創(chuàng)建WindowsService
下面演示了使用VisualStudio2019創(chuàng)建一個(gè)基于.NetFramework的Windows服務(wù)

項(xiàng)目結(jié)構(gòu)如下所示:
包含了一個(gè)啟動(dòng)項(xiàng)以及一個(gè)服務(wù)類

右鍵查看 Service1代碼, 如下所示, 包含了重寫OnStart方法以及OnStop方法:
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}當(dāng)服務(wù)被啟動(dòng), 即啟動(dòng)OnStart方法內(nèi)執(zhí)行的代碼, 而在ServiceBase當(dāng)中, 同樣提供了多種類型的方法被重寫。

當(dāng)我們寫完了該服務(wù)的執(zhí)行代碼之后, 下一步我們要為其添加一個(gè)安裝程序。
雙擊Service1.cs, 然后右鍵添加安裝程序,如下所示:

此時(shí), 項(xiàng)目結(jié)構(gòu)當(dāng)中新增了一個(gè)默認(rèn)名:ProjectInstaller.cs類, 而對(duì)應(yīng)的設(shè)計(jì)頁(yè)面如下所示:

serviceProcessInstaller1:
查看該類的屬性,如下所示:

說(shuō)明:
Account: 默認(rèn)設(shè)置為User, 當(dāng) Account 屬性為時(shí) User , Username 和 Password 屬性用于定義用于運(yùn)行服務(wù)應(yīng)用程序的帳戶。
Username和 Password 對(duì)允許服務(wù)在除系統(tǒng)帳戶之外的其他帳戶下運(yùn)行。 例如,如果沒有用戶登錄,則可以允許服務(wù)在重新啟動(dòng)時(shí)自動(dòng)啟動(dòng)。 如果保留 Username 或 Password 為空,并且將設(shè)置 Account 為 User ,則在安裝時(shí)系統(tǒng)將提示您輸入有效的用戶名和密碼。
還可以指定服務(wù)在本地系統(tǒng)帳戶下運(yùn)行,或以本地或網(wǎng)絡(luò)服務(wù)運(yùn)行。 ServiceAccount有關(guān)帳戶類型的詳細(xì)信息,請(qǐng)參閱枚舉:

serviceInstaller1:
查看該類的屬性,如下所示:

注: 該類擴(kuò)展 ServiceBase 來(lái)實(shí)現(xiàn)服務(wù)。 在安裝服務(wù)應(yīng)用程序時(shí)由安裝實(shí)用工具調(diào)用該類。
說(shuō)明:
- DelayedAutoStart : 若要延遲該服務(wù)的自動(dòng)啟動(dòng),則為 true;否則為 false。 默認(rèn)值為 false。
- Description : 服務(wù)的說(shuō)明。 默認(rèn)值為空字符串("")。
- DisplayName : 與服務(wù)關(guān)聯(lián)的名稱,常用于交互工具。
- ServiceName: 要安裝的服務(wù)的名稱。 該值必須在安裝實(shí)用工具嘗試安裝服務(wù)以前進(jìn)行設(shè)置。
- ServicesDependedOn : 在與該安裝程序關(guān)聯(lián)的服務(wù)運(yùn)行以前必須運(yùn)行的一組服務(wù)。
- StartType : 表示服務(wù)的啟動(dòng)方式。 默認(rèn)值為 Manual,指定在計(jì)算機(jī)重新啟動(dòng)后服務(wù)將不會(huì)自動(dòng)啟動(dòng)。
控制WindowsService
創(chuàng)建完成服務(wù)之后, 接下來(lái)就是針對(duì)服務(wù)進(jìn)行控制, 現(xiàn)在,可以使用 ServiceController 類來(lái)連接和控制現(xiàn)有服務(wù)的行為。
ServiceController: 表示 Windows 服務(wù)并允許連接到正在運(yùn)行或者已停止的服務(wù)、對(duì)其進(jìn)行操作或獲取有關(guān)它的信息。
通過(guò)ServiceController,我們可以獲取本機(jī)的Service服務(wù),以及啟動(dòng)、暫停、延續(xù)、掛起、關(guān)閉、刷新等動(dòng)作, 如下所示:

下面的示例演示如何使用 ServiceController 類來(lái)控制 Service1 服務(wù)示例。
using System;
using System.ServiceProcess;
using System.Diagnostics;
using System.Threading;
namespace ServiceControllerSample
{
class Program
{
public enum SimpleServiceCustomCommands
{ StopWorker = 128, RestartWorker, CheckWorker };
static void Main(string[] args)
{
ServiceController[] scServices;
scServices = ServiceController.GetServices();
foreach (ServiceController scTemp in scServices)
{
if (scTemp.ServiceName == "Service1")
{
// Display properties for the Simple Service sample
// from the ServiceBase example.
ServiceController sc = new ServiceController("Simple Service");
Console.WriteLine("Status = " + sc.Status);
Console.WriteLine("Can Pause and Continue = " + sc.CanPauseAndContinue);
Console.WriteLine("Can ShutDown = " + sc.CanShutdown);
Console.WriteLine("Can Stop = " + sc.CanStop);
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
while (sc.Status == ServiceControllerStatus.Stopped)
{
Thread.Sleep(1000);
sc.Refresh();
}
}
// Issue custom commands to the service
// enum SimpleServiceCustomCommands
// { StopWorker = 128, RestartWorker, CheckWorker };
sc.ExecuteCommand((int)SimpleServiceCustomCommands.StopWorker);
sc.ExecuteCommand((int)SimpleServiceCustomCommands.RestartWorker);
sc.Pause();
while (sc.Status != ServiceControllerStatus.Paused)
{
Thread.Sleep(1000);
sc.Refresh();
}
Console.WriteLine("Status = " + sc.Status);
sc.Continue();
while (sc.Status == ServiceControllerStatus.Paused)
{
Thread.Sleep(1000);
sc.Refresh();
}
Console.WriteLine("Status = " + sc.Status);
sc.Stop();
while (sc.Status != ServiceControllerStatus.Stopped)
{
Thread.Sleep(1000);
sc.Refresh();
}
Console.WriteLine("Status = " + sc.Status);
String[] argArray = new string[] { "ServiceController arg1", "ServiceController arg2" };
sc.Start(argArray);
while (sc.Status == ServiceControllerStatus.Stopped)
{
Thread.Sleep(1000);
sc.Refresh();
}
Console.WriteLine("Status = " + sc.Status);
// Display the event log entries for the custom commands
// and the start arguments.
EventLog el = new EventLog("Application");
EventLogEntryCollection elec = el.Entries;
foreach (EventLogEntry ele in elec)
{
if (ele.Source.IndexOf("Service1.OnCustomCommand") >= 0 |
ele.Source.IndexOf("Service1.Arguments") >= 0)
Console.WriteLine(ele.Message);
}
}
}
}
}
}
//This sample displays the following output if the Simple Service
//sample is running:
//Status = Running
//Can Pause and Continue = True
//Can ShutDown = True
//Can Stop = True
//Status = Paused
//Status = Running
//Status = Stopped
//Status = Running
//4:14:49 PM - Custom command received: 128
//4:14:49 PM - Custom command received: 129
//ServiceController arg1
//ServiceController arg2安裝WindowsService
能夠控制我們創(chuàng)建的服務(wù)的前提是, 該服務(wù)已安裝在我們調(diào)試的設(shè)備上, 我們可以通過(guò)AssemblyInstaller 類來(lái)進(jìn)行安裝。
安裝示例
在下面的示例中, AssemblyInstaller 通過(guò)調(diào)用 AssemblyInstaller 構(gòu)造函數(shù)來(lái)創(chuàng)建。 設(shè)置此對(duì)象的屬性,并 Install Commit 調(diào)用和方法以安裝 MyAssembly.exe 程序集。
using System;
using System.Configuration.Install;
using System.Collections;
using System.Collections.Specialized;
class AssemblyInstaller_Example
{
static void Main()
{
IDictionary mySavedState = new Hashtable();
Console.WriteLine( "" );
try
{
// Set the commandline argument array for 'logfile'.
string[] commandLineOptions = new string[ 1 ] {"/LogFile=example.log"};
// Create an object of the 'AssemblyInstaller' class.
AssemblyInstaller myAssemblyInstaller = new
AssemblyInstaller( "MyAssembly.exe" , commandLineOptions );
myAssemblyInstaller.UseNewContext = true;
// Install the 'MyAssembly' assembly.
myAssemblyInstaller.Install( mySavedState );
// Commit the 'MyAssembly' assembly.
myAssemblyInstaller.Commit( mySavedState );
}
catch (Exception e)
{
Console.WriteLine( e.Message );
}
}
}卸載示例
下面的示例演示的 Uninstall 方法 Installer 。 Uninstall方法在的派生類中被重寫 Installer 。
// Override 'Uninstall' method of Installer class.
public override void Uninstall( IDictionary mySavedState )
{
if (mySavedState == null)
{
Console.WriteLine("Uninstallation Error !");
}
else
{
base.Uninstall( mySavedState );
Console.WriteLine( "The Uninstall method of 'MyInstallerSample' has been called" );
}
}到此這篇關(guān)于C#創(chuàng)建控制Windows服務(wù)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 圖解如何使用C#創(chuàng)建Windows服務(wù)
- C#創(chuàng)建Windows服務(wù)的圖文教程
- C#創(chuàng)建Windows服務(wù)與服務(wù)的安裝、卸載
- C#用Topshelf創(chuàng)建Windows服務(wù)的步驟分享
- C#創(chuàng)建Windows服務(wù)的實(shí)現(xiàn)方法
- 使用C#創(chuàng)建Windows服務(wù)的實(shí)例代碼
- C#通過(guò)創(chuàng)建Windows服務(wù)啟動(dòng)程序的方法詳解
- c#創(chuàng)建windows服務(wù)入門教程實(shí)例
- c#創(chuàng)建windows服務(wù)(Windows Services)詳細(xì)步驟
- Visual Studio C#創(chuàng)建windows服務(wù)程序
相關(guān)文章
解析C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范
這篇文章主要介紹了C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范,這里我們根據(jù)C#語(yǔ)言的開發(fā)方微軟給出的約定來(lái)作為編寫樣式參照,需要的朋友可以參考下2016-01-01
C#基于SerialPort類實(shí)現(xiàn)串口通訊詳解
這篇文章主要為大家詳細(xì)介紹了C#基于SerialPort類實(shí)現(xiàn)串口通訊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
C#使用OpenCvSharp實(shí)現(xiàn)圖像校正
這篇文章主要為大家詳細(xì)介紹了C#如何使用OpenCvSharp實(shí)現(xiàn)圖像校正功能,文中的示例代碼簡(jiǎn)潔易懂,具有一定的學(xué)習(xí)價(jià)值,需要的小伙伴可以參考下2023-11-11
C#實(shí)現(xiàn)語(yǔ)音播報(bào)功能的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用C#實(shí)現(xiàn)語(yǔ)音播報(bào)功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2024-02-02
C#實(shí)現(xiàn)發(fā)送手機(jī)驗(yàn)證碼功能
之前基于c#實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能很復(fù)雜,真正做起來(lái)也就那回事,不過(guò)就是一個(gè)post請(qǐng)求就可以實(shí)現(xiàn)的東西,今天小編把思路分享到腳本之家平臺(tái),供大家參考下2017-06-06

