.NET Framework*给了现成的类库可以很便利的实现对windows处事的安置、卸载、启动、遏制、获取运行状态等成果。这些类都在System.ServiceProcess定名空间下。
安置window处事using (AssemblyInstaller installer = new AssemblyInstaller()) { installer.UseNewContext = true; installer.Path = serviceFilePath; //serviceFilePath是windows处事可执行文件的完整路径 IDictionary savedState = new Hashtable(); installer.Install(savedState); installer.Commit(savedState); }
卸载windows处事using (AssemblyInstaller installer = new AssemblyInstaller()) { installer.UseNewContext = true; installer.Path = serviceFilePath; installer.Uninstall(null); }
启动windows处事//使用ServiceController.GetServices()可获取windows处事列表,进而可判断处事是否存在 //serviceName是注册的windows处事名称 using (ServiceController control = new ServiceController(serviceName)) { if (control.Status == ServiceControllerStatus.Stopped) { control.Start(); } }
坑一切都似乎很简单,略坑的是,ServiceController.Start要领(注意并不是StartAsync),看起来是一个同步要领,如果处事启动掉败,,按理会异常抛出。而实际情况却时,Start要领是当即返回的,不会期待处事的启动功效。要领注释里产生异常只有两种情形:
System.ComponentModel.Win32Exception: 访谒系统 API 时堕落。
System.InvalidOperationException: 未找随处事。
至于其它情形导致的启动掉败(如文件缺掉、处事应用措施内部堕落),Start要领一无所知。
ServiceController类有一个Wait要领,感化是梗阻当前线程期待处事达到指定的状态,还可以设置期待的超不时间,这有必然的用处,但并不抱负。当启动掉败的时候,如何能够获取到启动掉败的信息呢?
一个鄙陋的步伐windows处事启动无论告成还是掉败,城市记录一条windows日志,可以借助对windows日志的监控来实现:
在挪用ServiceController.Start要领之前,启动对windows日志的监听:
_eventLog = new EventLog("Application"); _eventLog.EnableRaisingEvents = true; _eventLog.EntryWritten += Log_EntryWritten;
在EntryWritten事件措置惩罚惩罚器里,判断windows日志类型,进而得知windows处事启动情况:
private void Log_EntryWritten(object sender, EntryWrittenEventArgs e) { EventLogEntry log = e.Entry; if(log.Source == _currentSection.ServiceName) { if(log.EntryType == EventLogEntryType.Information) { //启动告成 } else { //启动掉败 MessageBox.Show(log.Message); } _eventLog.Dispose(); _eventLog = null; } }
这里还一个略坑的点,按一般的事件开发约定,sender参数应该就是产生事件的主体,在这里想来应该就是EventLog类的实例,然而事实上sender是EventLogInternal类的实例,很遗憾的是,这个类并不果然访谒,而且,也并未发明有跟EventLog类的直接关联。