使用工具安装,运行,停止,卸载Window服务

WSWinForm.exe介绍

      WSWinForm.exe是我自己开发的一个实用的小工具,用于将任何EXE程序作为Windows服务运行。也就是说WSWinForm只是其注册程序的服务外壳,这个特性对于我们来说非常实用,我们可以通过它来安装,运行,停止,卸载Windows服务,而不再是通过命令行InstallUtil的方式来安装。

资源下载

      你可以通过本文下载。

应用程序

源代码

最新版本信息查看

  GitHub地址:https://github.com/CrazyJson/TaskManager

  SVN地址:http://code.taobao.org/svn/TaskManagerPub/Branch

如何使用

      下载完软件以后,我们能干些什么呢?看看这个截图吧:。

这里可以看到的操作:

1. 安装指定路径的服务,

2. 运行指定服务,

3. 停止正在运行的服务,

4. 卸载服务,

这些功能是怎么通过代码来实现的呢,我后面再说。先对它有个印象就可以了。

代码解析

1.安装功能:

 1                 string[] cmdline = { };
 2                 string serviceFileName = txtPath.Text.Trim();
 3                 string serviceName = GetServiceName(serviceFileName);
 4                 if (string.IsNullOrEmpty(serviceName))
 5                 {
 6                     txtTip.Text = "指定文件不是Windows服务!";
 7                     return;
 8                 }
 9                 if (ServiceIsExisted(serviceName))
10                 {
11                     txtTip.Text = "要安装的服务已经存在!";
12                     return;
13                 }
14                 TransactedInstaller transactedInstaller = new TransactedInstaller();
15                 AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
16                 transactedInstaller.Installers.Add(assemblyInstaller);
17                 transactedInstaller.Install(new System.Collections.Hashtable());
18                 txtTip.Text = "服务安装成功!";            

 上面这段代码中最为中要的部分是方法 GetServiceName,通过给定路径获取服务的名称。下面来看看这个方法是怎么实现的。

 1  /// <summary>
 2         /// 获取Windows服务的名称
 3         /// </summary>
 4         /// <param name="serviceFileName">文件路径</param>
 5         /// <returns>服务名称</returns>
 6         private string GetServiceName(string serviceFileName)
 7         {
 8             try
 9             {
10                 Assembly assembly = Assembly.LoadFrom(serviceFileName);
11                 Type[] types = assembly.GetTypes();
12                 foreach (Type myType in types)
13                 {
14                     if (myType.IsClass && myType.BaseType == typeof(System.Configuration.Install.Installer))
15                     {
16                         FieldInfo[] fieldInfos = myType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Default | BindingFlags.Instance | BindingFlags.Static);
17                         foreach (FieldInfo myFieldInfo in fieldInfos)
18                         {
19                             if (myFieldInfo.FieldType == typeof(System.ServiceProcess.ServiceInstaller))
20                             {
21                                 ServiceInstaller serviceInstaller = (ServiceInstaller)myFieldInfo.GetValue(Activator.CreateInstance(myType));
22                                 return serviceInstaller.ServiceName;
23                             }
24                         }
25                     }
26                 }
27                 return "";
28             }
29             catch (Exception ex)
30             {
31                 throw ex;
32             }
33         }

 1.加载程序集

 2.获取程序集里面继承于System.Configuration.Install.Installer这个类的类,原因在于Windows服务都需要添加一个安装程序,而安装程序是继承这个类的,

 安装以后的服务名称是通过这个类ServiceInstaller的变量指定的,比如ServiceInstaller.ServiceName = "xxx";

 3.获取第二步Installer类里面的ServiceInstaller变量的值,然后获取这个值的ServiceName属性就是服务的名称。

 2.运行功能:

 1 try
 2             {
 3                 string serviceName = GetServiceName(txtPath.Text.Trim());
 4                 if (string.IsNullOrEmpty(serviceName))
 5                 {
 6                     txtTip.Text = "指定文件不是Windows服务!";
 7                     return;
 8                 }
 9                 if (!ServiceIsExisted(serviceName))
10                 {
11                     txtTip.Text = "要运行的服务不存在!";
12                     return;
13                 }
14                 ServiceController service = new ServiceController(serviceName);
15                 if (service.Status != ServiceControllerStatus.Running && service.Status != ServiceControllerStatus.StartPending)
16                 {
17                     service.Start();
18                     txtTip.Text = "服务运行成功!";
19                 }
20                 else
21                 {
22                     txtTip.Text = "服务正在运行!";
23                 }
24             }
25             catch (Exception ex)
26             {
27                 txtTip.Text = ex.InnerException.ToString();
28             }

重要的是ServiceController这个类,这个类可以获取系统中所有的服务

 1         /// <summary>
 2         /// 判断服务是否已经存在
 3      /// </summary>
 4         /// <param name="serviceName">服务名称</param>
 5         /// <returns>bool</returns>
 6         private bool ServiceIsExisted(string serviceName)
 7         {
 8             ServiceController[] services = ServiceController.GetServices();
 9             foreach (ServiceController s in services)
10             {
11                 if (s.ServiceName == serviceName)
12                 {
13                     return true;
14                 }
15             }
16             return false;
17         }

 3.停止功能:

 1 ry
 2             {
 3                 string[] cmdline = { };
 4                 string serviceFileName = txtPath.Text.Trim();
 5                 string serviceName = GetServiceName(serviceFileName);
 6                 if (string.IsNullOrEmpty(serviceName))
 7                 {
 8                     txtTip.Text = "指定文件不是Windows服务!";
 9                     return;
10                 }
11                 if (!ServiceIsExisted(serviceName))
12                 {
13                     txtTip.Text = "要停止的服务不存在!";
14                     return;
15                 }
16                 ServiceController service = new ServiceController(serviceName);
17                 if (service.Status == ServiceControllerStatus.Running)
18                 {
19                     service.Stop();
20                     txtTip.Text = "服务停止成功!";
21                 }
22                 else
23                 {
24                     txtTip.Text = "服务已经停止!";
25                 }
26 
27             }
28             catch (Exception ex)
29             {
30                 txtTip.Text = ex.InnerException.ToString();
31             }

4.卸载功能:

 1  try
 2             {
 3                 string[] cmdline = { };
 4                 string serviceFileName = txtPath.Text.Trim();
 5                 string serviceName = GetServiceName(serviceFileName);
 6                 if (string.IsNullOrEmpty(serviceName))
 7                 {
 8                     txtTip.Text = "指定文件不是Windows服务!";
 9                     return;
10                 }
11                 if (!ServiceIsExisted(serviceName))
12                 {
13                     txtTip.Text = "要卸载的服务不存在!";
14                     return;
15                 }
16                 TransactedInstaller transactedInstaller = new TransactedInstaller();
17                 AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
18                 transactedInstaller.Installers.Add(assemblyInstaller);
19                 transactedInstaller.Uninstall(null);
20                 txtTip.Text = "服务卸载成功!";
21 
22             }
23             catch (Exception ex)
24             {
25                 txtTip.Text = ex.InnerException.ToString();
26             }

总结

1.整体来说实现了服务的整个功能,可以方便的运行停止服务,而不再是使用命令行的方式。

2.下一篇将讲解,使用Windows服务实现任务处理(及定时执行某个功能)。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏醉梦轩

编译可用的Android模拟器ranchu内核

1652
来自专栏大数据

数据科学工具 Jupyter Notebook 教程(二)

Jupyter Notebook 是一个把代码、图像、注释、公式和作图集于一处,实现可读性分析的交互式笔记本工具。借助所谓的内核(Kernel)的概念,Jupy...

2237
来自专栏bboysoul

Koadic的安装和使用

Koadic是DEFCON分型出来的一个后渗透工具,主要通过vbscript、jscript进行大部分操作 废话不多说开始演示

835
来自专栏拂晓风起

cocos2d-js 在线更新代码脚本 动态更新脚本程序 热更新 绕过平台审核 不需重新上架

794
来自专栏SpringSpace.cn

RHEL 4.7 (64bit) 环境安装 GCC 4.6 测试记录 (更新至gcc-4.6.1)

Red Hat Enterprise Linux AS release 4 (Nahant Update 7)

1082
来自专栏JackeyGao的博客

Karabiner profile 命令行切换方式

Karabiner 提供了一个命令行工具来方便脚本编程, 一般这个命令行工具在安装包的bin目录下, 具体地址为: /Applications/Karabine...

693
来自专栏数据和云

【Oracle字符集】识别及转换导出文件的字符集

编辑手记:很多人在进行数据库导入导出操作的时候会遇到字符集的问题,今日拣选了 《循序渐进Oracle》一书中的相关章节,希望对初学Oracle的朋友有所帮助。 ...

3334
来自专栏乐沙弥的世界

publickey,gssapi-with-mic,Unspecified GSS failure

        最近的MHA配置时碰到了Permission denied (publickey,gssapi-with-mic,password)这个错误提示...

632
来自专栏杂烩

spring安全框架Security(二) 转

首先是<security:authentication-manager>是指定我们自定义的身份验证策略,这里我们用customUserDetailsServ...

753
来自专栏Samego开发资源

It can make your ssh login simply as well as efficiently on Mac or Linux

It can make your ssh login simply as well as efficiently on Mac or LInux. 点我翻译 ...

672

扫码关注云+社区