好久沒來了,說要寫博的,但人懶……一直沒寫過。最近做一個功能,這樣的可能以后很少用到,時間久不用,可能還會忘記,還是寫篇記錄下來吧。
公司業務里,有一項需求,需要監控數據庫里的某些數值,當數值減少到預設值時,就通過短信提醒用戶,這種功能做在IIS上似乎不太穩定,如果IIS重啟之類的,就經常會出現一些問題。后來就想,能否做成windows的服務,只要服務器開着,這項服務就隨系統開啟啟動,不受其他影響。
隨后就實現了這個功能。
第一步,新建一個windowsService服務

在windows桌面下,有windows服務,項目名稱自定義吧。我就改成公司項目的名稱了Fanso2o_MonitoringActivity
第二步,先寫業務吧,單擊切換到代碼視圖吧。

第三步,業務處理

哎呀,截圖太麻煩了,直接上代碼。
1 public partial class Service1 : ServiceBase 2 { 3 //因為業務不多,就直接寫在這里面了。如果業務多,最好還是另外封裝。 4 public static List<UserMonitor> user = new List<UserMonitor>(); 5 6 //創建一個定時執行檢查的全局對象。我的時間是寫在配置文件里的,可以修改的,此處直接上數字了。 7 public static readonly Timer timer = new Timer(1800000); 8 public Service1() 9 { 10 InitializeComponent(); 11 } 12 /// <summary> 13 /// 服務啟動,執行定時檢查任務。 14 /// </summary> 15 /// <param name="args"></param> 16 protected override void OnStart(string[] args) 17 { 18 //將業務方法添加到定時執行的對象事件中, 19 timer.Elapsed += new ElapsedEventHandler(Time); 20 timer.AutoReset = true; 21 timer.Enabled = true; 22 } 23 24 /// <summary> 25 /// 服務關閉 26 /// </summary> 27 protected override void OnStop() 28 { 29 timer.Close(); 30 timer.Dispose(); 31 32 } 33 34 /// <summary> 35 /// 服務重啟 36 /// </summary> 37 protected override void OnContinue() 38 { 39 timer.Start(); 40 base.OnContinue(); 41 } 42 43 /// <summary> 44 /// 服務暫停 45 /// </summary> 46 protected override void OnPause() 47 { 48 timer.Stop(); 49 base.OnPause(); 50 } 51 52 /// <summary> 53 /// 執行業務的方法 54 /// </summary> 55 /// <param name="source"></param> 56 /// <param name="e"></param> 57 public static async void Time(object source, System.Timers.ElapsedEventArgs e) 58 { 59 await MonitoringActivity(); 60 } 61 62 /// <summary> 63 /// 具體業務的異步方法 64 /// </summary> 65 /// <returns></returns> 66 static async Task<bool> MonitoringActivity() 67 { 68 return await Task.Run<bool>(() => 69 { 70 //具體的業務方法,根據自己的需要寫吧。 71 var defaultSmsService = new DefaultSmsService(); 72 var activityMonitorDao = new MongoCommonDao<ActivityMonitor, string>(); 73 var groupDao = new MongoCommonDao<CompanyResourceGroup, string>(); 74 var resourceDao = new MongoCommonDao<CompanyResource, string>(); 75 var monitorList = activityMonitorDao.Set.FindAll().ToList(); 76 77 var group = 78 groupDao.Set.Find(Query<CompanyResourceGroup>.In(x => x.Id, 79 monitorList.Select(c => c.ActivityGroupid))) 80 .SetFields(new string[] { "Title", "Amount", "GetAmount" }).ToList(); 81 monitorList.ForEach(x => 82 { 83 x.MonitorPerson.ForEach(c => 84 { 85 if (user.All(y => y.Name != c.MonitorName && y.Phone != c.Phone)) 86 { 87 var u = new UserMonitor 88 { 89 Phone = c.Phone, 90 Name = c.MonitorName, 91 CompanyGroup = new List<CompanyResourceGroup>(), 92 count = 0, 93 SenCount = -1 94 }; 95 user.Add(u); 96 } 97 var g = group.Find(h => h.Id == x.ActivityGroupid); 98 if (g != null && g.Residue <= 50) 99 { 100 var index = user.FindIndex(h => h.Name == c.MonitorName && h.Phone == c.Phone); 101 if (index>-1&&user[index].CompanyGroup.All(h => h.Id != x.ActivityGroupid)) 102 { 103 user[index].count++; 104 user[index].CompanyGroup.Add(g); 105 } 106 } 107 else if (g != null && g.Residue > 50) 108 { 109 var index = user.FindIndex(h => h.Name == c.MonitorName && h.Phone == c.Phone); 110 if (index > -1 && user[index].CompanyGroup.Any(h => h.Id == x.ActivityGroupid)) 111 { 112 user[index].CompanyGroup.RemoveAll(h => h.Id == x.ActivityGroupid); 113 user[index].count--; 114 } 115 } 116 }); 117 }); 118 if (user.Any()) 119 { 120 var smsStr = new List<SmsModel>(); 121 user.ForEach(x => 122 { 123 if (x.count > 0 && x.SenCount < x.count) 124 { 125 var m = new SmsModel(); 126 m.PhoneList = x.Phone; 127 m.SmsStr.Add(x.count.ToString()); 128 var str = new StringBuilder(); 129 var num = x.CompanyGroup.Count > 3 ? 3 : x.CompanyGroup.Count; 130 for (int i = 0; i < num; i++) 131 { 132 str.Append(x.CompanyGroup[i].Title + ","); 133 } 134 m.SmsStr.Add(str.ToString()); 135 x.SenCount = x.count; 136 137 //發送短信的具體方法 138 var s = defaultSmsService.SendValidateCode(m.PhoneList, m.SmsStr); 139 Console.WriteLine(s); 140 } 141 }); 142 } 143 return true; 144 }); 145 } 146 } 147 148 /// <summary> 149 /// 一些用到的類 150 /// </summary> 151 public class UserMonitor 152 { 153 public string Name { get; set; } 154 public string Phone { get; set; } 155 public int count { get; set; } 156 public int SenCount { get; set; } 157 public List<CompanyResourceGroup> CompanyGroup { get; set; } 158 159 public UserMonitor() 160 { 161 this.CompanyGroup = new List<CompanyResourceGroup>(); 162 this.Name = string.Empty; 163 this.Phone = string.Empty; 164 this.count = 0; 165 this.SenCount = -1; 166 } 167 } 168 169 /// <summary> 170 /// 一些用到的類 171 /// </summary> 172 public class SmsModel 173 { 174 public string PhoneList { get; set; } 175 public List<string> SmsStr { get; set; } 176 177 public SmsModel() 178 { 179 PhoneList = string.Empty; 180 SmsStr = new List<string>(); 181 } 182 }
業務處理完,就在service1中添加安裝程序

第五步,在設置中,添加安裝程序。會出現下圖:

這兩個是服務安裝的一些組件。
第六步,分別在這兩個組件上鼠標右鍵,選擇屬性,進行相應的設置。

displayName是服務顯示在服務列表中的名字,可以根據需要填寫。
serviceName是服務執行注冊到系統中的名字,不可與其他服務重名。如果displayName沒填寫,那顯示在服務列表中的,將是此屬性中的名字。
starType是設置服務運行的方式,可以進行選擇。

Account是服務的啟動方式,也可以進行選擇,LocalSystem是隨系統啟動而自動啟動。
第七步,業務處理完畢后,就生成服務(最好用管理員權限運行VS2013,此處是個坑,害我檢查了好久,我的不知道為什么,必需用管理員權限生成的,安裝服務時,才不會報錯,否則就有問題。)
第八步,服務生成完畢后,打開bin\Debug目錄,新建兩個文本文件,一個用來安裝服務,另一個用來刪除服務的。

Install.text里面放如下代碼:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe D:\C#\Fanso2o_MonitoringActivity\Fanso2o_MonitoringActivity\bin\Debug\Fanso2o_MonitoringActivity.exe
Net Start Fanso2o_MonitoringActivity
sc config Fanso2o_MonitoringActivity start= auto
pause
Uninstall.text里面放如下代碼:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u D:\C#\Fanso2o_MonitoringActivity\Fanso2o_MonitoringActivity\bin\Debug\Fanso2o_MonitoringActivity.exe
pause
這兩段代碼的具體含意,
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe就是調用.net的一個服務安裝程序,來執行服務的安裝和刪除。【.net的安裝程序,默認是裝在系統盤下的那個位置,如果有改變,請更改為具體的路徑】
此段代碼后面跟着的是服務所在的文件夾的路徑和服務的可執行文件。我是放在D盤下的,因此寫D盤下的路徑。可根據需要更改。
Net Start Fanso2o_MonitoringActivity 服務安裝好后,立刻執行服務。
sc config Fanso2o_MonitoringActivity start= auto 設置服務的啟動方式為自動。其實已經在代碼里設置過了,這個地方沒必要。
以上全部改好后,將Install.tex、Uninstall.text兩個文件的后綴名改為bat,就可以執行服務的安裝和刪除了。
【注意一:執行此兩個文件時,需要用管理員權限執行,否則就會報錯。】
【注意二:服務安裝后,請不要改動源代碼重新生成,否則會刪除不掉。如必需改動源代碼,請先刪除服務,刪除后再改動生成,重新安裝】

