操作Windows服务需要3种:
服务程序
服务控制程序
服务配置程序
服务程序需要3部分:主函数、service-main函数、处理程序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; namespace QuoteServer { public class QuoteServer { private TcpListener listener; private int port; private string filename; private List<string> quotes; private Random random; private Thread listenerThread; public QuoteServer() : this("quotes.txt") { } public QuoteServer(string filename) : this(filename, 7890) { } public QuoteServer(string filename, int port) { this.filename = filename; this.port = port; } protected void ReadQuotes() { quotes = File.ReadAllLines(filename).ToList(); random = new Random(); } protected string GetRandomQuoteOfTheDay() { int index = random.Next(0,quotes.Count); return quotes[index]; } public void Start() { ReadQuotes(); listenerThread = new Thread(ListenerThread); listenerThread.IsBackground = true; listenerThread.Name = "Listener"; listenerThread.Start(); } protected void ListenerThread() { try { IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); listener = new TcpListener(ipAddress, port); listener.Start(); while (true) { Socket clientSocket = listener.AcceptSocket(); string message = GetRandomQuoteOfTheDay(); UnicodeEncoding encoder = new UnicodeEncoding(); byte[] buffer = encoder.GetBytes(message); clientSocket.Send(buffer, buffer.Length, 0); clientSocket.Close(); } } catch (SocketException ex) { Trace.TraceError(string.Format("QuoteServer {0}",ex.Message)); } } public void Stop() { listener.Stop(); } public void Suspend() { listener.Stop(); } public void Resume() { Start(); } public void RefreshQuotes() { ReadQuotes(); } } }
服务控制管理器(Servcie Control Manager,SCM)
SCM是操作系统的一个组成部分,它的作用是与服务进行通信
服务负责为它的每一个服务都注册一个service-main函数。
service-main函数一个重要任务是用SCM注册一个处理程序
处理程序必须响应SCM的事件
服务控制程序可以把停止、暂停和继续服务的请求发送给SCM
服务控制程序独立于SCM和服务本身
System.ServiceProcess名称空间中实现服务的3部分的服务类:
必须从ServiceBase类继承才可以实现服务
ServiceController类用于实现服务控制程序
ServiceProcessInstaller类和ServiceInstaller类用于安装和配置服务程序
ServiceBase类是所有用.NET Framework开发的Windows服务的基类
ServiceBase基类的Run()方法,使用SCM中NativeMethods.StartServiceCtrlDispather()方法注册ServiceMainCallback()方法,并把记录写到事件日志中
处理程序在ServiceCommandCallback()方法中执行
当改变了对服务的请求时,SCM调用ServiceCommandCallback()方法
ServiceCommandCallback()方法再把请求发送给OnPause()、OnContinue()、OnStop ()、OnCustomCommand()和OnPowerEvent()
using System; using System.Collections.Generic; using System.Linq; using System.ServiceProcess; using System.Text; namespace QuoteServer { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new QuoteServer() }; ServiceBase.Run(ServicesToRun); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; namespace QuoteServer { public partial class QuoteServer : ServiceBase { public QuoteServer() { InitializeComponent(); } protected override void OnStart(string[] args) { } protected override void OnStop() { } } }
服务的设计视图,右键添加安装程序
新建一个ProjectInstaller类、一个ServiceInstaller实例和一个ServiceProcessInstaller实例
namespace QuoteServer { partial class ProjectInstaller { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region 组件设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller(); // // serviceProcessInstaller1 // this.serviceProcessInstaller1.Password = null; this.serviceProcessInstaller1.Username = null; // // serviceInstaller1 // this.serviceInstaller1.ServiceName = "Service1"; // // ProjectInstaller // this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.serviceProcessInstaller1, this.serviceInstaller1}); } #endregion private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; private System.ServiceProcess.ServiceInstaller serviceInstaller1; } }
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Configuration.Install; using System.Linq; namespace QuoteServer { [RunInstaller(true)] public partial class ProjectInstaller : System.Configuration.Install.Installer { public ProjectInstaller() { InitializeComponent(); } } }
installutil.exe实用程序安装和卸载服务
installutil quoteservice.exe
installutil /u quoteservice.exe
Service MMC管理单元对服务进行监视和控制
net.exe 可以控制服务
sc.exe 命令行实用程序