前言

在我们的工作中,经常遇到Windows服务的安装和卸载,在之前公司也普写过一个WinForm程序选择安装路径,这次再来个小巧灵活的控制台程序,不用再选择,只需放到需要安装服务的目录中运行就可以实现安装或卸载。

开发思路

1、由于系统的权限限制,在运行程序时需要以管理员身份运行

2、因为需要实现安装和卸载两个功能,在程序运行时提示本次操作是安装还是卸载  需要输入 1 或 2

3、接下来程序会查找当前目录中的可执行文件并过滤程序本身和有时我们复制进来的带有vhost的文件,并列出列表让操作者选择(一般情况下只有一个)

4、根据用户所选进行安装或卸载操作

5、由于可能重复操作,需要递归调用一下

具体实现

首先们要操作服务,需要用  System.ServiceProcess 来封装实现类

  1. using System;
  2. using System.Collections;
  3. using System.Configuration.Install;
  4. using System.Linq;
  5. using System.ServiceProcess;
  6.  
  7. namespace AutoInstallUtil
  8. {
  9. public class SystemServices
  10. {
  11. /// <summary>
  12. /// 打开系统服务
  13. /// </summary>
  14. /// <param name="serviceName">系统服务名称</param>
  15. /// <returns></returns>
  16. public static bool SystemServiceOpen(string serviceName)
  17. {
  18. try
  19. {
  20. using (var control = new ServiceController(serviceName))
  21. {
  22. if (control.Status != ServiceControllerStatus.Running)
  23. {
  24. control.Start();
  25. }
  26. }
  27. return true;
  28. }
  29. catch
  30. {
  31. return false;
  32. }
  33. }
  34.  
  35. /// <summary>
  36. /// 关闭系统服务
  37. /// </summary>
  38. /// <param name="serviceName">系统服务名称</param>
  39. /// <returns></returns>
  40. public static bool SystemServiceClose(string serviceName)
  41. {
  42. try
  43. {
  44. using (var control = new ServiceController(serviceName))
  45. {
  46.  
  47. if (control.Status == ServiceControllerStatus.Running)
  48. {
  49. control.Stop();
  50. }
  51. }
  52. return true;
  53. }
  54. catch
  55. {
  56. return false;
  57. }
  58. }
  59.  
  60. /// <summary>
  61. /// 重启系统服务
  62. /// </summary>
  63. /// <param name="serviceName">系统服务名称</param>
  64. /// <returns></returns>
  65. public static bool SystemServiceReStart(string serviceName)
  66. {
  67. try
  68. {
  69. using (var control = new ServiceController(serviceName))
  70. {
  71. if (control.Status == System.ServiceProcess.ServiceControllerStatus.Running)
  72. {
  73. control.Continue();
  74. }
  75. }
  76. return true;
  77. }
  78. catch
  79. {
  80. return false;
  81. }
  82. }
  83.  
  84. /// <summary>
  85. /// 返回服务状态
  86. /// </summary>
  87. /// <param name="serviceName">系统服务名称</param>
  88. /// <returns>1:服务未运行 2:服务正在启动 3:服务正在停止 4:服务正在运行 5:服务即将继续 6:服务即将暂停 7:服务已暂停 0:未知状态</returns>
  89. public static int GetSystemServiceStatus(string serviceName)
  90. {
  91. try
  92. {
  93. using (var control = new ServiceController(serviceName))
  94. {
  95. return (int)control.Status;
  96. }
  97. }
  98. catch
  99. {
  100. return ;
  101. }
  102. }
  103.  
  104. /// <summary>
  105. /// 返回服务状态
  106. /// </summary>
  107. /// <param name="serviceName">系统服务名称</param>
  108. /// <returns>1:服务未运行 2:服务正在启动 3:服务正在停止 4:服务正在运行 5:服务即将继续 6:服务即将暂停 7:服务已暂停 0:未知状态</returns>
  109. public static string GetSystemServiceStatusString(string serviceName)
  110. {
  111. try
  112. {
  113. using (var control = new ServiceController(serviceName))
  114. {
  115. var status = string.Empty;
  116. switch ((int)control.Status)
  117. {
  118. case :
  119. status = "服务未运行";
  120. break;
  121. case :
  122. status = "服务正在启动";
  123. break;
  124. case :
  125. status = "服务正在停止";
  126. break;
  127. case :
  128. status = "服务正在运行";
  129. break;
  130. case :
  131. status = "服务即将继续";
  132. break;
  133. case :
  134. status = "服务即将暂停";
  135. break;
  136. case :
  137. status = "服务已暂停";
  138. break;
  139. case :
  140. status = "未知状态";
  141. break;
  142. }
  143. return status;
  144. }
  145. }
  146. catch
  147. {
  148. return "未知状态";
  149. }
  150. }
  151.  
  152. /// <summary>
  153. /// 安装服务
  154. /// </summary>
  155. /// <param name="stateSaver"></param>
  156. /// <param name="filepath"></param>
  157. public static void InstallService(IDictionary stateSaver, string filepath)
  158. {
  159. try
  160. {
  161. var myAssemblyInstaller = new AssemblyInstaller
  162. {
  163. UseNewContext = true,
  164. Path = filepath
  165. };
  166. myAssemblyInstaller.Install(stateSaver);
  167. myAssemblyInstaller.Commit(stateSaver);
  168. myAssemblyInstaller.Dispose();
  169. }
  170. catch (Exception ex)
  171. {
  172. throw new Exception("installServiceError/n" + ex.Message);
  173. }
  174. }
  175.  
  176. public static bool ServiceIsExisted(string serviceName)
  177. {
  178. ServiceController[] services = ServiceController.GetServices();
  179. return services.Any(s => s.ServiceName == serviceName);
  180. }
  181.  
  182. /// <summary>
  183. /// 卸载服务
  184. /// </summary>
  185. /// <param name="filepath">路径和文件名</param>
  186. public static void UnInstallService(string filepath)
  187. {
  188. try
  189. {
  190. //UnInstall Service
  191. var myAssemblyInstaller = new AssemblyInstaller
  192. {
  193. UseNewContext = true,
  194. Path = filepath
  195. };
  196. myAssemblyInstaller.Uninstall(null);
  197. myAssemblyInstaller.Dispose();
  198. }
  199. catch (Exception ex)
  200. {
  201. throw new Exception("unInstallServiceError/n" + ex.Message);
  202. }
  203. }
  204. }
  205. }

接下来我们封装控制台的操作方法为了实现循环监听这里用了递归

  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Linq;
  5.  
  6. namespace AutoInstallUtil
  7. {
  8. class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. try
  13. {
  14. ServerAction();
  15. }
  16. catch (Exception ex)
  17. {
  18. Console.WriteLine("发生错误:{0}", ex.Message);
  19. }
  20.  
  21. Console.ReadKey();
  22. }
  23.  
  24. /// <summary>
  25. /// 操作
  26. /// </summary>
  27. private static void ServerAction()
  28. {
  29. Console.WriteLine("请输入:1安装 2卸载");
  30. var condition = Console.ReadLine();
  31. var currentPath = Environment.CurrentDirectory;
  32. var currentFileNameVshost = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName).ToLower();
  33. var currentFileName = currentFileNameVshost.Replace(".vshost.exe", ".exe");
  34. var files =
  35. Directory.GetFiles(currentPath)
  36. .Select(o => Path.GetFileName(o).ToLower())
  37. .ToList()
  38. .Where(
  39. o =>
  40. o != currentFileNameVshost
  41. && o != currentFileName
  42. && o.ToLower().EndsWith(".exe")
  43. && o != "installutil.exe"
  44. && !o.ToLower().EndsWith(".vshost.exe"))
  45. .ToList();
  46. if (files.Count == )
  47. {
  48. Console.WriteLine("未找到可执行文件,请确认当前目录有需要安装的服务程序");
  49. }
  50. else
  51. {
  52. Console.WriteLine("找到目录有如下可执行文件,请选择需要安装或卸载的文件序号:");
  53. }
  54. int i = ;
  55. foreach (var file in files)
  56. {
  57. Console.WriteLine("序号:{0} 文件名:{1}", i, file);
  58. i++;
  59. }
  60. var serviceFileIndex = Console.ReadLine();
  61. var servicePathName = currentPath + "\\" + files[Convert.ToInt32(serviceFileIndex)];
  62. if (condition == "")
  63. {
  64. SystemServices.InstallService(null, servicePathName);
  65. }
  66. else
  67. {
  68. SystemServices.UnInstallService(servicePathName);
  69. }
  70. Console.WriteLine("**********本次操作完毕**********");
  71. ServerAction();
  72. }
  73. }
  74. }

到此为止简单的安装程序就写完了,为了醒目我选了个红色的西红柿来做为图标,这样显示些

源码和程序

http://pan.baidu.com/s/1qWqXG4W    提取码:piq4

C#版Windows服务安装卸载小工具-附源码的更多相关文章

  1. 原创SQlServer数据库生成简单的说明文档包含(存储过程、视图、数据库批量备份)小工具(附源码)

    这是一款简单的数据库文档生成工具,主要实现了SQlServer生成说明文档的小工具,目前不够完善,主要可以把数据库的表以及表的详细字段信息,导出到 Word中,可以方便开发人员了解数据库的信息或写技术 ...

  2. 原创SQlServer数据库生成简单的说明文档小工具(附源码)

    这是一款简单的数据库文档生成工具,主要实现了SQlServer生成说明文档的小工具,目前不够完善,主要可以把数据库的表以及表的详细字段信息,导出到 Word中,可以方便开发人员了解数据库的信息或写技术 ...

  3. Zookeeper Windows版的服务安装和管理工具

    以前研究过负载均衡,最近正在项目上实施(从来没做过小项目以上级别的东西,哈).然后遇到了多个一模一样但是同时运行的服务.不同服务但依赖同相同的配置数据(前端网页服务:Nginx+IIS+nodejs. ...

  4. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  5. leaflet结合geoserver利用WFS服务实现图层删除功能(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  6. Nginx Windows版的服务安装和管理工具

    以前研究过负载均衡,最近正在项目上实施(从来没做过小项目以上级别的东西,哈),nginx挺好,不过Windows有点为难,小流量和本地不追求性能,简单易用是目标. Nginx Windows上并没有提 ...

  7. 2.Windows服务-->安装卸载服务

    1.使用vs组件“VS2012开发人员命令提示” 工具,进行安装卸载服务(必须以“管理员身份运行") 安装和卸载的时候选择合适的安装程序工具地址,例如: 安装服务:C:\Windows\Mi ...

  8. windows服务安装卸载

    到C盘下找到对应的开发VS的installutil.exe文件,复制到程序的执行文件(*.exe)相同目录下在开始程序中找到VS命令提示工具 转到程序的执行文件(*.exe)目录下 C:\>cd ...

  9. openlayers6结合geoserver利用WFS服务实现图层新增功能(附源码下载)

    内容概览 1.openlayers6结合geoserver利用WFS服务实现图层新增功能2.源代码demo下载 效果图如下: 本篇主要是openlayers6通过调用geoserver发布的地图服务W ...

随机推荐

  1. Uploadify 上传文件插件详解

    Uploadify 上传文件插件详解 Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中 ...

  2. python基础语法(2)

    2. 元组 tuple和list十分相似,但是tuple是不可变的,即不能修改tuple,元组通过圆括号中用逗号分割的项定义:支持索引和切片操作:可以使用 in 查看一个元素是否在tuple中.空元组 ...

  3. [转]MySQL中存储过程权限问题

    MySQL中以用户执行存储过程的权限为EXECUTE 比如我们在名为configdb的数据库下创建了如下存储过程,存储过程的定义者为user_admin use configdb; drop proc ...

  4. jsp_属性范围_request

    request属性范围表示在服务器跳转后,所有设置的内容依然会被保留下来.(服务器端跳转:页面跳转,地址栏不发生变化) 下面写个小例子测试下: (1)request_demo.jsp <%@ p ...

  5. github 仓库管理

    一.远程仓库有master和dev分支1. 克隆代码 git clone https://github.com/master-dev.git # 这个git路径是无效的,示例而已 2. 查看所有分支 ...

  6. pmcyg 1.0 发布,Cygwin 安装包创建工具

    pmcyg 1.0 改进包列表中对 UTF-8 的支持. pmcyg是一种工具来创建自定义集合的Cygwin包 连同Cygwin安装程序.这使得创建独立的分布而无需镜整个组Cygwin包.例如,它可以 ...

  7. IIS 7.5 + asp.net MVC4 设置路由处理URL请求

    使用asp.net MVC4开发的网站,在本地的VS012环境下运行,一切正常.但当发布到Windows 2008 R2(IIS7.5 + Framework4.5)上时,访问相关网页时,出现有下面的 ...

  8. 简单理解在Mac OS X上运行ASP.NET程序

    运行ASP.NET程序的三要素: 1) CLR(.NET运行时) 2) KRE(ASP.NET运行时) 3) Web服务器 所以在Mac OS X上运行ASP.NET程序,就需要对应这三要素的东西: ...

  9. 设计模式之美:Command(命令)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):直接注入 Receiver 对象,Command 决定调用哪个方法. 实现方式(二):注入 Receiver 的指定方法, ...

  10. thrift之TTransport层的分帧传输类TFramedTransport

    帧传输类就是按照一帧的固定大小来传输数据,所有的写操作首先都是在内存中完成的直到调用了flush操作,然后传输节点在flush操作之后将所有数据根据数据的有效载荷写入数据的长度的二进制块发送出去,允许 ...