使用工具安装,运行,停止,卸载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 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Git远程库版本回滚

1474
来自专栏重庆的技术分享区

Git 多分支管理亲手操作一波

834
来自专栏前端桃园

git 大法,玩转版本管理

最近有小伙伴问我 git 应该怎么学,我觉得 git 就是多用就会了,把常用的命令先看两边,然后再在实际过程中运用,忘了再去查一查,用多了就记住了,当然这只是代...

502
来自专栏散尽浮华

Gerrit上分支操作记录(创建分支、删除分支)

Git分支对于一个项目的代码管理而言,是十分重要的!许多久用git的朋友可能已经掌握的很牢固了,但对于一些初涉git的童鞋来说,可能还不是很熟悉。 在此,我将自...

5285
来自专栏Android群英传

一篇文章,教你学会Git

551
来自专栏青玉伏案

Git常用命令

 以下是学习git时常用的命令,大致总结了以下,用git做版本控制所用的命令挺多的,但常用的也在大脑承受的范围之中,把自己总结的东西给大家分享一下。   1....

1948
来自专栏软件开发

一个小时学会Git

最近要与部门同事一起做技术分享,我选择了Git,因为Git 是一种在全球范围都广受欢迎的版本控制系统。在开发过程中,为了跟踪代码,文档,项目等信息中的变化,版本...

2775
来自专栏fangyangcoder

Git笔记

可以在GitHub下载离线版的笔记,链接如下:https://github.com/FangYang970206/GitNote,觉得不错的话,欢迎fork和s...

1122
来自专栏iOS 开发杂谈

学习笔记之git命令行的详细使用

git仓库,你可以简单理解成一个目录,这个目录里面的所有文件都可以被git仓库管理起来,每个文件的修改、删除,git都能跟踪,以便任何时刻都可以追踪历史,或者在...

662
来自专栏张善友的专栏

Git远程库版本回滚

在git的一般使用中,如果发现错误的将不想staging的文件add进入index之后,想回退取消,这就叫做git代码库回滚: 指的是将代码库某分支退回到以前的...

1815

扫码关注云+社区