网上很多创建Widows Service 的方法,其安装和运行服务的方式大多是通过cmd 命令来实现的,这里将通过控制台的形式实现安装、运行和卸载服务。
主页代码:
1 using KQService.Job; 2 using KQService.Utils; 3 using System; 4 using System.Collections.Generic; 5 using System.Configuration; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 namespace KQService.WS 12 { 13 static class Program 14 { 15 static string ServiceName = ConfigurationManager.AppSettings["ServiceName"]; 16 /// <summary> 17 /// 应用程序的主入口点。 18 /// </summary> 19 static void Main(string[] args) 20 { 21 //带参启动运行服务 22 if (args.Length > 0) 23 try 24 { 25 ServiceBase[] serviceToRun = new ServiceBase[] { new ServiceInit() }; 26 ServiceBase.Run(serviceToRun); 27 } 28 catch (Exception ex) 29 { 30 LogHelper.Error("服务异常:\r\n" + ex.Message + "\r\n" + ex.InnerException); 31 } 32 33 34 //不带参启动配置程序 35 else 36 { 37 ServiceInstallWindow(); 38 } 39 40 Console.ReadKey(); 41 } 42 /// <summary> 43 /// 启动安装服务界面 44 /// </summary> 45 static void ServiceInstallWindow() 46 { 47 while (true) 48 { 49 Console.WriteLine("请选择你要执行的操作:"); 50 Console.WriteLine("1运行服务"); 51 Console.WriteLine("2停止服务"); 52 Console.WriteLine("3安装服务"); 53 Console.WriteLine("4卸载服务"); 54 Console.WriteLine("5验证服务状态"); 55 Console.WriteLine("6退出"); 56 Console.WriteLine("————————————————————"); 57 58 char keyChar = Console.ReadKey().KeyChar; 59 60 //运行服务 61 if (keyChar == '1') 62 { 63 Console.WriteLine("\r\n服务已启动,请稍后......"); 64 if (ServiceHelper.IsServiceExisted(ServiceName)) 65 { 66 ServiceHelper.StartService(ServiceName); 67 Console.WriteLine("\r\n服务已启动!"); 68 } 69 else 70 { 71 Console.WriteLine("\r\n服务不存在......"); 72 } 73 } 74 //停止服务 75 if (keyChar == '2') 76 { 77 Console.WriteLine("\r\n服务正在停止,请稍后......"); 78 if (ServiceHelper.IsServiceExisted(ServiceName)) 79 { 80 ServiceHelper.StopService(ServiceName); 81 Console.WriteLine("\r\n服务已停止!"); 82 } 83 else 84 { 85 Console.WriteLine("\r\n服务不存在......"); 86 } 87 } 88 //安装服务 89 else if (keyChar == '3') 90 { 91 if (!ServiceHelper.IsServiceExisted(ServiceName)) 92 { 93 ServiceHelper.ConfigService(ServiceName, true); 94 } 95 else 96 { 97 Console.WriteLine("\r\n服务已存在......"); 98 } 99 } 100 //卸载服务 101 else if (keyChar == '4') 102 { 103 if (ServiceHelper.IsServiceExisted(ServiceName)) 104 { 105 ServiceHelper.ConfigService(ServiceName, false); 106 } 107 else 108 { 109 Console.WriteLine("\r\n服务不存在......"); 110 } 111 } 112 //验证服务 113 else if (keyChar == '5') 114 { 115 if (!ServiceHelper.IsServiceExisted(ServiceName)) 116 { 117 Console.WriteLine("\r\n服务不存在......"); 118 } 119 else 120 { 121 Console.WriteLine("\r\n服务状态:" + ServiceHelper.GetServiceStatus(ServiceName).ToString()); 122 } 123 } 124 //退出 125 else if (keyChar == '6') 126 { 127 break; 128 } 129 else 130 { 131 Console.WriteLine("\r\n请输入一个有效键!"); 132 Console.WriteLine("————————————————————"); 133 } 134 } 135 } 136 } 137 }
ServiceHelper 代码:
using System; using System.Threading; using System.Reflection; using System.Collections; using System.ServiceProcess; using System.Configuration.Install; namespace RabbitMQClientService.Common { public class ServiceHelper { #region 服务是否存在 /// <summary> /// 服务是否存在 /// </summary> /// <param name="serviceName">服务名</param> /// <returns></returns> public static bool IsServiceExisted(string serviceName) { ServiceController[] services = ServiceController.GetServices(); foreach (ServiceController s in services) { if (s.ServiceName == serviceName) { return true; } } return false; } #endregion #region 启动服务 /// <summary> /// 启动服务 /// </summary> /// <param name="serviceName">服务名</param> public static void StartService(string serviceName) { using (ServiceController service = new ServiceController(serviceName)) { //判断服务状态 if (service.Status != ServiceControllerStatus.Running && service.Status != ServiceControllerStatus.StartPending) { try { service.Start(); //启动服务 for (int i = 0; i < 60; i++) { service.Refresh(); Thread.Sleep(1000); if (service.Status == ServiceControllerStatus.StartPending || service.Status == ServiceControllerStatus.Running) //判断服务是否正常运行 { break; } if (i == 59) { LogHelper.WriteErrorLog("启动服务失败:" + serviceName, null); } } } catch (Exception ex) { LogHelper.WriteErrorLog("启动服务失败:" + ex.Message, ex); } } } } #endregion #region 停止服务 /// <summary> /// 停止服务 /// </summary> /// <param name="serviceName">服务名</param> public static void StopService(string serviceName) { using (ServiceController service = new ServiceController(serviceName)) { //判断服务状态 if (service.Status == ServiceControllerStatus.StartPending || service.Status == ServiceControllerStatus.Running) { try { if (service.CanStop) { // 如果权限不够是不能Stop()的。 service.Stop(); // 这句话如果没有对该服务的后续操作可以不要,C#程序只是以权限向操作系统发出关闭某服务的消息而已,真正关闭该服务的是操作系统而非此C#程序(下面的Start的也一样) service.WaitForStatus(ServiceControllerStatus.Stopped); } } catch (Exception ex) { LogHelper.WriteErrorLog("停止服务失败: \r\n" + ex.Message, ex); } } } } #endregion #region 获取服务状态 /// <summary> /// 获取服务状态 /// </summary> /// <param name="serviceName">服务名</param> /// <returns></returns> public static ServiceControllerStatus GetServiceStatus(string serviceName) { ServiceController service = new ServiceController(serviceName); return service.Status; } #endregion #region 配置服务(安装和卸载) /// <summary> /// 配置服务(安装和卸载) /// </summary> /// <param name="serviceName">服务名</param> /// <param name="install">是否安装,true安装,false 卸载</param> public static void ConfigService(string serviceName, bool install) { TransactedInstaller ti = new TransactedInstaller(); ti.Installers.Add(new ServiceProcessInstaller { Account = ServiceAccount.LocalSystem }); ti.Installers.Add(new ServiceInstaller { DisplayName = serviceName, ServiceName = serviceName, Description = "考勤数据同步", StartType = ServiceStartMode.Automatic//运行方式 }); ti.Context = new InstallContext(); ti.Context.Parameters["assemblypath"] = "\"" + Assembly.GetEntryAssembly().Location + "\" /service"; if (install) //是否安装服务 { ti.Install(new Hashtable()); } else { ti.Uninstall(null); } } #endregion } }
该方法主要引用了 System.ServiceProcess.ServiceController 类,
界面效果如下: