zoukankan      html  css  js  c++  java
  • Windows Service的安装卸载 和 Service控制(转)

    Windows Service的安装卸载 和 Service控制

    原文地址:http://www.cnblogs.com/Peter-Zhang/archive/2011/10/15/2212663.html

      本文内容包括如何通过C#代码安装Windows Service(exe文件,并非打包后的安装文件)、判断Service是否存在、获得Service状态及启动停止Service。

      创建Windows Service项目并Build得到exe文件,如何创建 Service 可参考 创建windows service 并打包成安装文件

    一、 Windows服务的安装和卸载

      安装和卸载服务可以使用 .NET 工具installutil.exe (eg:安装-> installutil xxx.exe 卸载-> installutil /u xxx.exe),使用ManagedInstallerClass可以实现安装卸载Windows 服务,ManagedInstallerClass 在System.Configuration.Install命名空间下。

      实现如下:

    复制代码
     1         ///<summary> 2 /// 使用Windows Service对应的exe文件 安装Service
     3 /// 和 installutil xxx.exe 效果相同
     4 ///</summary> 5 ///<param name="installFile">exe文件(包含路径)</param> 6 ///<returns>是否安装成功</returns> 7         public static bool InstallServie(string installFile)
     8         {
     9             string[] args = { installFile };
    10             try
    11             {
    12                 ManagedInstallerClass.InstallHelper(args);
    13                 return true;
    14             }
    15             catch
    16             {
    17                 return false;
    18             }
    19         }
    20 
    21         ///<summary>22 /// 使用Windows Service对应的exe文件 卸载Service
    23 /// 和 installutil /u xxx.exe 效果相同
    24 ///</summary>25 ///<param name="installFile">exe文件(包含路径)</param>26 ///<returns>是否卸载成功</returns>27         public static bool UninstallService(string installFile)
    28         {
    29             string[] args = { "/u", installFile };
    30             try
    31             {
    32                 // 根据文件获得服务名,假设exe文件名和服务名相同33                 string tmp = installFile;
    34                 if (tmp.IndexOf('\') != -1)
    35                 {
    36                     tmp = tmp.Substring(tmp.LastIndexOf('\') + 1);
    37                 }
    38                 string svcName = tmp.Substring(0, tmp.LastIndexOf('.'));
    39                 // 在卸载服务之前 要先停止windows服务40                 StopService(svcName);
    41 
    42                 ManagedInstallerClass.InstallHelper(args);
    43                 return true;
    44             }
    45             catch
    46             {
    47                 return false;
    48             }
    49         }
    复制代码

      注意: 服务删除前需要先停止服务,否则服务被标记为禁用,并无法删除。原因:系统删除服务时,首先是标记服务为“删除”,等待服务的所有引用完全断开后,服务才被完全删除。当服务引用未完全断开时,就删除服务,系统将服务锁死为“禁用”状态,并禁止其他操作,注意此时服务尚未完全删除。所以对已删除后立即重装的服务,需要完全释放与服务相关的所有引用,此时系统才真正完全删除服务,之后才能再次安装服务。如果出现服务禁用问题,检查代码,哪些地方有服务引用,同时检查是否其他程序还在引用,也要终止这些引用程序。

    二、Windows服务的状态获取和控制

      使用ServiceController来获取服务状态或对服务进行控制。

      ServiceController 表示 Windows 服务并允许连接到正在运行或者已停止的服务、对其进行操作或获取有关它的信息。使用 ServiceController类连接到现有服务并控制其行为。当创建 ServiceController 类的实例时,设置其属性,以便它与特定的 Windows 服务交互作用。然后可以使用此类来启动、停止和以其他方式操作该服务创建实例后,必须为其设置两个属性来标识与其交互的服务:计算机名称和要控制的服务的名称。默认情况下,MachineName 设置为本地计算机,因此不需要更改它,除非想将该实例设置为指向另一台计算机。

      服务可以处理的命令集取决于该服务的属性;例如,可以将服务的 CanStop 属性设置为 false。该设置使 Stop 命令在那个特定的服务上不可用;它禁用了必要的按钮,使您无法从 SCM 中停止服务。如果试图通过代码停止服务,系统将引发错误,并显示错误信息“未能停止 servicename”。

    常用操作如下:

      1.  获得Service对应的ServiceController实例

    复制代码
     1         ///<summary> 2 /// 获得service对应的ServiceController对象  3 ///</summary> 4 ///<param name="serviceName">服务名</param> 5 ///<returns>ServiceController对象,若没有该服务,则返回null</returns> 6         public static ServiceController GetService(string serviceName)  7         {  8             ServiceController[] services = ServiceController.GetServices();  9             foreach (ServiceController s in services) 10             { 11                 if (s.ServiceName == serviceName) 12                 { 13                     return s; 14                 } 15             } 16             return null; 17         }
    复制代码

      2.  检查指定的服务是否存在

    复制代码
     1         ///<summary> 2 /// 检查指定的服务是否存在。  
     3 ///</summary> 4 ///<param name="serviceName">要查找的服务名字</param> 5 ///<returns>是否存在</returns> 6         public static bool ServiceExisted(string serviceName)
     7         {
     8             if (GetService(serviceName) == null)
     9             {
    10                 return false;
    11             }
    12             else
    13             {
    14                 return true;
    15             }
    16         }
    复制代码

      3. 获得服务详细信息

    复制代码
     1         ///<summary> 2 /// 获得Service的详细信息  3 ///</summary> 4 ///<param name="serviceName">服务名</param> 5 ///<returns>Service信息,保存在string中</returns> 6         public static string GetServiceInfo(string serviceName)  7         {  8             StringBuilder details = new StringBuilder();  9  10             ServiceController sc = GetService(serviceName); 11  12             if (sc == null) 13             { 14                 return string.Format("{0} 不存在!", serviceName); 15             } 16  17             details.AppendLine(string.Format("服务标识的名称: {0}", sc.ServiceName)); 18             details.AppendLine(string.Format("服务友好名称:{0}", sc.DisplayName)); 19             details.AppendLine(string.Format("服务在启动后是否可以停止: {0}", sc.CanStop)); 20             details.AppendLine(string.Format("服务所驻留的计算机的名称: {0}", sc.MachineName)); // "." 表示本地计算机21             details.AppendLine(string.Format("服务类型: {0}", sc.ServiceType.ToString())); 22             details.AppendLine(string.Format("服务状态: {0}", sc.Status.ToString())); 23  24             // DependentServices 获取依赖于与此 ServiceController 实例关联的服务的服务集。25             StringBuilder dependentServices = new StringBuilder(); 26             foreach (ServiceController s in sc.DependentServices) 27             { 28                 dependentServices.Append(s.ServiceName + ", "); 29             } 30             details.AppendLine(string.Format("依赖于与此 ServiceController 实例关联的服务的服务: {0}", dependentServices.ToString())); 31              32             // ServicesDependedOn 此服务所依赖的服务集。33             StringBuilder serviceDependedOn = new StringBuilder(); 34             foreach (ServiceController s in sc.ServicesDependedOn) 35             { 36                 serviceDependedOn.Append(s.ServiceName + ", "); 37             } 38             details.AppendLine(string.Format("此服务所依赖的服务: {0}", serviceDependedOn.ToString())); 39  40             return details.ToString(); 41         }
    复制代码

      4.  启动服务

    复制代码
     1         ///<summary> 2 /// 启动服务
     3 ///</summary> 4 ///<param name="serviceName">服务名</param> 5 ///<returns>是否启动成功</returns> 6         public static bool StartService(string serviceName)
     7         {
     8             ServiceController sc = GetService(serviceName);
     9 
    10             if (sc.Status != ServiceControllerStatus.Running)
    11             {
    12                 try
    13                 {
    14                     sc.Start();
    15                     sc.WaitForStatus(ServiceControllerStatus.Running);  // 等待服务达到指定状态16                 }
    17                 catch
    18                 {
    19                     return false;
    20                 }
    21             }
    22 
    23             return true;
    24         }
    复制代码

      5.  停止服务

    复制代码
     1         ///<summary> 2 /// 停止服务  3 ///</summary> 4 ///<param name="serviceName">服务名</param> 5 ///<returns>是否停止服务成功,如果服务启动后不可以停止,则抛异常</returns> 6         public static bool StopService(string serviceName)  7         {  8             ServiceController sc = GetService(serviceName);  9  10             if (!sc.CanStop) 11             { 12                 throw new Exception(string.Format("服务{0}启动后不可以停止.", serviceName)); 13             } 14  15             if (sc.Status != ServiceControllerStatus.Stopped) 16             { 17                 try 18                 { 19                     sc.Stop(); 20                     sc.WaitForStatus(ServiceControllerStatus.Stopped);  // 等待服务达到指定状态21                 } 22                 catch 23                 { 24                     return false; 25                 } 26             } 27  28             return true; 29         }
    复制代码
     
     
     
  • 相关阅读:
    struts2的@Result annotation 如何添加params,并且在页面取值
    spring @Entity @Table
    @Results( 中 params 怎么用
    Java三种技术架构
    python 内存管理
    wxpyhon 鼠标事件例子
    常用wxPython事件描述
    wxpython 拖动界面时进入假死状态(未响应)解决方法
    python 的一些高级编程技巧
    python 访问器@property的使用方法
  • 原文地址:https://www.cnblogs.com/lenmom/p/3437545.html
Copyright © 2011-2022 走看看