C# windows service 程序
0.概述:
工程结构
1.新建windows service工程
2.编写服务程序
新建项
编写代码
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.ServiceModel; 10 11 namespace WindowsService_Test 12 { 13 public partial class Service1 : ServiceBase 14 { 15 public Service1() 16 { 17 InitializeComponent(); 18 } 19 private ServiceHost host; 20 protected override void OnStart(string[] args) 21 { 22 Logger.Write("服务启动......"); 23 try 24 { 25 host = new ServiceHost(typeof(TestAgentService)); 26 host.Open(); 27 } 28 catch (Exception ex) 29 { 30 Logger.WriteException("服务ErpInnerService启动失败.", ex); 31 } 32 string msg = string.Empty; 33 if (!new ServiceWorker().Start(ref msg)) 34 { 35 throw new Exception(msg); 36 } 37 Logger.Write("服务启动成功."); 38 } 39 40 protected override void OnStop() 41 { 42 host.Close(); 43 } 44 } 45 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace WindowsService_Test 7 { 8 class TestAgentService 9 { 10 private static int i=0; 11 /// <summary> 12 /// 执行循环处理 13 /// </summary> 14 public static void DoScanWork() 15 { 16 i++; 17 Logger.Write("循环调用DoScanWork["+i+"]次"); 18 } 19 } 20 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace WindowsService_Test 7 { 8 class ServiceWorker 9 { 10 private static System.Threading.Timer timer; 11 public bool Start(ref string msg) 12 { 13 try 14 { 15 if (ConfigHelper.ScannerEnable) 16 { 17 timer = new System.Threading.Timer(new System.Threading.TimerCallback(this.DoScanWork), null, 1000, ConfigHelper.GetScanInterval()); 18 Logger.Write("服务线程启动成功."); 19 } 20 return true; 21 } 22 catch (System.Exception ex) 23 { 24 Logger.WriteException("【启动服务线程】", ex); 25 return false; 26 } 27 } 28 public bool Stop(ref string msg) 29 { 30 if (timer != null) 31 { 32 try 33 { 34 timer.Dispose(); 35 timer = null; 36 } 37 catch (Exception ex) 38 { 39 Logger.WriteException("【关闭服务线程】", ex); 40 msg = ex.Message; 41 return false; 42 } 43 } 44 return true; 45 } 46 public static object _lock = new object(); 47 private bool idleFlag = true; 48 private int collectioncount = 0; 49 private void DoScanWork(object o) 50 { 51 lock (_lock) 52 { 53 if (!idleFlag) 54 { 55 Logger.Write("worker is busy!"); 56 return; 57 } 58 try 59 { 60 idleFlag = false; 61 TestAgentService.DoScanWork(); 62 } 63 catch (Exception ex) 64 { 65 Logger.WriteException("【Erp DoScanWork】", ex); 66 } 67 finally 68 { 69 idleFlag = true; 70 collectioncount++; 71 if (collectioncount >= 1) 72 { 73 try 74 { 75 System.GC.Collect(); 76 collectioncount = 0; 77 } 78 catch (Exception ex) 79 { 80 Logger.WriteException("【Erp DoScanWork Collect】", ex); 81 } 82 } 83 } 84 } 85 } 86 } 87 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 7 namespace WindowsService_Test 8 { 9 /// <summary> 10 /// 记录文件日志 11 /// </summary> 12 public static class Logger 13 { 14 private static string Dir = AppDomain.CurrentDomain.BaseDirectory + "Logs"; 15 private static object _lockDebug = new object(); 16 private static object _lockException = new object(); 17 /// <summary> 18 /// 日志 19 /// </summary> 20 /// <param name="Message">日志</param> 21 /// <param name="LogType">分类</param> 22 /// <param name="SubDir">子目录</param> 23 public static void Write(string Message) 24 { 25 lock (_lockDebug) 26 { 27 try 28 { 29 StringBuilder sb = new StringBuilder(); 30 sb.Append(Dir); 31 if (!Directory.Exists(sb.ToString())) 32 { 33 Directory.CreateDirectory(sb.ToString()); 34 } 35 sb.Append(@"\"); 36 sb.Append(DateTime.Now.ToString("yyyy-MM-dd")); 37 sb.Append(".txt"); 38 StreamWriter writer = new StreamWriter(sb.ToString(), true, Encoding.UTF8); 39 StringBuilder sbSprit = new StringBuilder(); 40 sbSprit.Append("\r\n\r\n\r\n-------------------------------------------------------"); 41 sbSprit.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 42 sbSprit.Append("-------------------------------------------------------\r\n"); 43 writer.WriteLine(sbSprit.ToString()); 44 writer.WriteLine(Message); 45 writer.Flush(); 46 writer.Close(); 47 } 48 catch { } 49 } 50 } 51 /// <summary> 52 /// 日志 53 /// </summary> 54 /// <param name="Message">日志</param> 55 /// <param name="LogType">分类</param> 56 /// <param name="SubDir">子目录</param> 57 public static void Write(string Message, string LogType, string SubDir) 58 { 59 lock (_lockDebug) 60 { 61 try 62 { 63 StringBuilder sb = new StringBuilder(); 64 sb.Append(Dir); 65 if (!String.IsNullOrEmpty(SubDir)) 66 { 67 sb.Append(SubDir); 68 } 69 if (!Directory.Exists(sb.ToString())) 70 { 71 Directory.CreateDirectory(sb.ToString()); 72 } 73 sb.Append(@"\"); 74 if (!string.IsNullOrEmpty(LogType)) 75 { 76 sb.Append(LogType); 77 sb.Append("_"); 78 } 79 sb.Append(DateTime.Now.ToString("yyyy-MM-dd")); 80 sb.Append(".txt"); 81 StreamWriter writer = new StreamWriter(sb.ToString(), true, Encoding.UTF8); 82 StringBuilder sbSprit = new StringBuilder(); 83 sbSprit.Append("\r\n\r\n\r\n-------------------------------------------------------"); 84 sbSprit.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 85 sbSprit.Append("-------------------------------------------------------\r\n"); 86 writer.WriteLine(sbSprit.ToString()); 87 writer.WriteLine(Message); 88 writer.Flush(); 89 writer.Close(); 90 } 91 catch { } 92 } 93 } 94 /// <summary> 95 /// 异常日志 96 /// </summary> 97 /// <param name="Message">日志</param> 98 /// <param name="LogType">分类</param> 99 /// <param name="Ex">异常</param> 100 /// <param name="SubDir">子目录</param> 101 public static void WriteException(string Message, string LogType, Exception Ex, string SubDir) 102 { 103 lock (_lockException) 104 { 105 try 106 { 107 StringBuilder sb = new StringBuilder(); 108 sb.Append(Dir); 109 if (!string.IsNullOrEmpty(SubDir)) 110 { 111 sb.Append(SubDir); 112 } 113 if (!Directory.Exists(sb.ToString())) 114 { 115 Directory.CreateDirectory(sb.ToString()); 116 } 117 sb.Append(@"\"); 118 if (!string.IsNullOrEmpty(LogType)) 119 { 120 sb.Append(LogType + "-"); 121 } 122 sb.Append(DateTime.Now.ToString("yyyy-MM-dd") + "-exception.txt"); 123 StreamWriter writer = new StreamWriter(sb.ToString(), true, Encoding.UTF8); 124 StringBuilder sbSprit = new StringBuilder(); 125 sbSprit.Append("\r\n\r\n\r\n-------------------------------------------------------"); 126 sbSprit.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 127 sbSprit.Append("-------------------------------------------------------\r\n"); 128 writer.WriteLine(sbSprit); 129 writer.WriteLine("\r\n" + Message); 130 writer.WriteLine("\r\n" + Ex.Message); 131 writer.WriteLine("\r\n" + Ex.StackTrace); 132 Exception innerex = Ex.InnerException; 133 while (innerex != null) 134 { 135 writer.WriteLine("\r\n" + innerex.StackTrace); 136 innerex = innerex.InnerException; 137 } 138 writer.Flush(); 139 writer.Close(); 140 } 141 catch { } 142 } 143 } 144 /// <summary> 145 /// 异常日志 146 /// </summary> 147 /// <param name="Message">日志</param> 148 /// <param name="Ex">异常</param> 149 /// <param name="SubDir">子目录</param> 150 public static void WriteException(string Message, Exception Ex, string SubDir) 151 { 152 lock (_lockException) 153 { 154 try 155 { 156 StringBuilder sb = new StringBuilder(); 157 sb.Append(Dir); 158 if (!string.IsNullOrEmpty(SubDir)) 159 { 160 sb.Append(SubDir); 161 } 162 if (!Directory.Exists(sb.ToString())) 163 { 164 Directory.CreateDirectory(sb.ToString()); 165 } 166 sb.Append(@"\"); 167 sb.Append(DateTime.Now.ToString("yyyy-MM-dd") + "-exception.txt"); 168 StreamWriter writer = new StreamWriter(sb.ToString(), true, Encoding.UTF8); 169 StringBuilder sbSprit = new StringBuilder(); 170 sbSprit.Append("\r\n\r\n\r\n-------------------------------------------------------"); 171 sbSprit.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 172 sbSprit.Append("-------------------------------------------------------\r\n"); 173 writer.WriteLine(sbSprit); 174 writer.WriteLine("\r\n" + Message); 175 writer.WriteLine("\r\n" + Ex.Message); 176 writer.WriteLine("\r\n" + Ex.StackTrace); 177 Exception innerex = Ex.InnerException; 178 while (innerex != null) 179 { 180 writer.WriteLine("\r\n" + innerex.StackTrace); 181 innerex = innerex.InnerException; 182 } 183 writer.Flush(); 184 writer.Close(); 185 } 186 catch { } 187 } 188 } 189 /// <summary> 190 /// 异常日志 191 /// </summary> 192 /// <param name="Message">日志</param> 193 /// <param name="Ex">异常</param> 194 /// <param name="SubDir">子目录</param> 195 public static void WriteException(string Message, Exception Ex) 196 { 197 lock (_lockException) 198 { 199 try 200 { 201 StringBuilder sb = new StringBuilder(); 202 sb.Append(Dir); 203 if (!Directory.Exists(sb.ToString())) 204 { 205 Directory.CreateDirectory(sb.ToString()); 206 } 207 sb.Append(@"\"); 208 sb.Append(DateTime.Now.ToString("yyyy-MM-dd") + "-exception.txt"); 209 StreamWriter writer = new StreamWriter(sb.ToString(), true, Encoding.UTF8); 210 StringBuilder sbSprit = new StringBuilder(); 211 sbSprit.Append("\r\n\r\n\r\n-------------------------------------------------------"); 212 sbSprit.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 213 sbSprit.Append("-------------------------------------------------------\r\n"); 214 writer.WriteLine(sbSprit); 215 writer.WriteLine("\r\n" + Message); 216 writer.WriteLine("\r\n" + Ex.Message); 217 writer.WriteLine("\r\n" + Ex.StackTrace); 218 Exception innerex = Ex.InnerException; 219 while (innerex != null) 220 { 221 writer.WriteLine("\r\n" + innerex.StackTrace); 222 innerex = innerex.InnerException; 223 } 224 writer.Flush(); 225 writer.Close(); 226 } 227 catch { } 228 } 229 } 230 } 231 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace WindowsService_Test 7 { 8 class ConfigHelper 9 { 10 public static int GetScanInterval() 11 { 12 string interval = System.Configuration.ConfigurationSettings.AppSettings["ScanInterval"]; 13 return int.Parse(interval); 14 } 15 public static bool ScannerEnable 16 { 17 get 18 { 19 string scannerEnable = System.Configuration.ConfigurationSettings.AppSettings["ScannerEnable"]; 20 if (scannerEnable == "false") 21 { 22 return false; 23 } 24 return true; 25 } 26 } 27 28 } 29 }
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <appSettings> 4 <!--扫描间隔(毫秒)--> 5 <add key="ScanInterval" value="60000"/> 6 <!--扫描服务是否可用--> 7 <add key="ScannerEnable" value="true"/> 8 </appSettings> 9 </configuration>
代码编写完成后,打开service.cs,右键点击添加安装程序
添加安装程序后,工程下会自动添加ProjectInstaller.cs的项
现在开始设置serviceProcessInstaller1 和 serviceInstaller1 几个重要属性:
serviceInstaller1 :
StartType设置成Automatic【随机启动】
ServiceName【服务名称】
Description 【服务的描述】
DisplayName 【显示名称】
serviceProcessInstaller1 :
Account设置成LocalSystem【本地系统帐号】