.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类的直接关联。

C#管理windows服务的更多相关文章

  1. 玩转Windows服务系列——命令行管理Windows服务

    说到Windows服务的管理就不得不说通过命令行的方式管理Windows服务,因为无论是系统管理员,还是通过编程的方式调用cmd命令,命令行都是非常方便以及强大的工具. 接下来就看一下如何通过cmd命 ...

  2. 玩转Windows服务系列——命令行管理Windows服务

    原文:玩转Windows服务系列——命令行管理Windows服务 说到Windows服务的管理就不得不说通过命令行的方式管理Windows服务,因为无论是系统管理员,还是通过编程的方式调用cmd命令, ...

  3. [转]玩转Windows服务系列——命令行管理Windows服务

    本文转自:http://www.cnblogs.com/hbccdf/p/managewindowsservicewithcmd.html 说到Windows服务的管理就不得不说通过命令行的方式管理W ...

  4. 如何使用PowerShell管理Windows服务

    [TechTarget中国原创] 作为一名系统管理员,最常见的任务之一就是学会管理Windows服务,这是保证Windows服务器和客户端正常运行的重要内容. 许多操作系统和应用程序都依赖于这些服务. ...

  5. 第十三篇 一个安装、管理windows服务的桌面程序

    在网上看到一个修改程序入口的程序去把windows 服务修改成控制台的程序,然后利用控制台的程序把服务安装和管理,也想起自己原来也写了一个对windows 报务管理的程序,不过是winform的.   ...

  6. Windows Server 2016-命令行方式管理Windows服务

    Microsoft Windows 服务(过去称为 NT 服务)允许用户创建可在其自身的 Windows 会话中长时间运行的可执行应用程序. 这些服务可在计算机启动时自动启动,可以暂停和重启,并且不显 ...

  7. python管理Windows服务

    上一篇介绍了pywin32模块,它的win32service子模块提供了对服务管理API的包装,相关API如下: ChangeServiceConfig ChangeServiceConfig2 Cl ...

  8. 使用Topshelf管理Windows服务

    目的:以控制台方式开发Windows服务程序,调试部署方便. https://www.cnblogs.com/itjeff/p/8316244.html https://www.cnblogs.com ...

  9. 玩转Windows服务系列汇总

    玩转Windows服务系列汇总 创建Windows服务 Debug.Release版本的注册和卸载及其原理 无COM接口Windows服务启动失败原因及解决方案 服务运行.停止流程浅析 Windows ...

随机推荐

  1. [转]双线性插值(Bilinear interpolation)

    1,原理 在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值,兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中的插值效果和运算速度 ...

  2. Linux内核Ramdisk(initrd)机制【转】

    转自:http://www.cnblogs.com/armlinux/archive/2011/03/30/2396827.html 摘要:对于Linux用户来说,Ramdisk并不陌生,可是为什么需 ...

  3. PHP 生成、识别二维码及安装相关扩展/工具

    2018-02-20 00:30:26  更新:推荐新扩展(极力推荐) 这篇文章里用的两个二维码扩展都有些问题和麻烦:phpqrcode(生成二维码)的源码有点小 bug: 而 php-zbarcod ...

  4. poj1095

    题意:给出n,要求输出第n个二叉树,二叉树编号规则如下图所示: 分析:g[i]表示有i个节点的二叉树,有多少种.f[i][j]表示有i个节点,且左子树有j个节点的树有多少种. sumg[i]表示g数组 ...

  5. java基础24 线程、多线程及线程的生命周期(Thread)

    1.1.进程 正在执行的程序称作为一个进程.进程负责了内存空间的划分 疑问1:windows电脑称之为多任务的操作系统,那么Windows是同时运行多个应用程序呢? 从宏观的角度:windows确实在 ...

  6. 网络协议之UDP

    前言 TCP协议在不可靠的网络环境上提供了可靠的通信通道,隐藏了大量的底层细节,使应用程序更加简洁.但有些应用并不需要这么高的可靠性,并不需要按序交付,而且TCP为了提高可靠性也增加了延时,在某些对延 ...

  7. ZooKeeper的典型应用场景

    <从Paxos到Zookeeper 分布式一致性原理与实践>读书笔记 本文:总结脑图地址:脑图 前言 所有的典型应用场景,都是利用了ZK的如下特性: 强一致性:在高并发情况下,能够保证节点 ...

  8. C++ 必须使用初始化列表

    继承关系中,父类无默认构造函数 类类型类成员变量无默认构造函数 const类型成员变量 引用类型成员变量 不使用初始化列表,在创建对象调用构造函数之前会对所有的成员变量进行默认初始化,然后再执行构造函 ...

  9. 查找Mysql慢查询Sql语句

    一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_log 这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句. 2,long_query_tim ...

  10. Effective STL 学习笔记 Item 18: 慎用 vector<bool>

    vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...