.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 类的直接关联
来源: http://www.bubuko.com/infodetail-2507280.html