昨天一个朋友想用做个短信网关,与移动TCP/IP 通迅来完成短信的发送。并且想是用一个Windows 服务来完成这个工作,但是又想让管理员能在客户端(浏览器端)对服务进行装载,卸载,启动,停止。我初步听了以后,觉得这个需求是可以完成的,服务这个项目的建立没有问题,控制服务这个项目也是没有问题的。于是就研究了一下,并去网上搜集了一些资料,整理了一个从技术角度相对完整的文档,拿出来给大家分享一下。
为了简化业务,这里就把与短信网关通信的需求改成每间隔一秒钟向一个txt 文档写一个当前时间的需求。
我们先来看服务部分:
打开VS2008 ,“文件 →新建→项目 ”,选择“Windows ”项中的“Windows 服务”,根据自己的情况修跑径和名称,这里的名称修为“WriteTextService ”,确定后,出现一个“若要在类中添加组件,请从 工具箱 中拖出它们,然后例用属性窗口来设置它们的属性。若要为类创建方法和事件,请 单击此处切换到代码视图 。”的一个界面,我们如果处理业务逻辑,单击“单击此处切换到代码视图”,来转换到代码页。
代码
WriteTextService.cs
 
1using System;
2using System.ServiceProcess;
3using System.IO;
4using System.Threading;
5
6namespace WriteTextServiceNS
7{
8         public partial class WriteTextService : ServiceBase
9        {
10                 public WriteTextService()
11                {
12                        InitializeComponent();
13                }
14                protected override void OnStart(string[] args)
15                {
16                        Thread t = new Thread(new ThreadStart(DY));
17                        t.Start();                                            
18                }
19                private void DY()
20                {
21                         while (true)
22                        {
23                                 File.WriteAllText(@"F:/gsw.txt", DateTime.Now.ToString());
24                                Thread.Sleep(2000);
25                        }
26                }
27                protected override void OnStop()
28                {
29                }
30        }
31}
32
现在,我们还需要在服务中创建一个服务安装类,来完成服务初始化安装工作。
我们创建一个类ServiceInstall
ServiceInstall.cs
 
1using System.Collections;
2using System.Configuration.Install;
3using System.ServiceProcess;
4using System.ComponentModel;
5using Microsoft.Win32;
6
7namespace WriteTextServiceNS
8{    
9        [RunInstaller(true)]
10         public class ServiceInstall : Installer
11        {
12                private ServiceInstaller WTSerInst;    //它由安装实用工具用来将与服务关联的注册表值写入 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services 注册表项内的子项。
13                private ServiceProcessInstaller    WTProInst;    //安装实用工具使用它来写与要安装服务关联的注册表值。
14                 public ServiceInstall()
15                {
16                        WTProInst = new ServiceProcessInstaller();
17                        WTProInst.Account = ServiceAccount.LocalSystem;    //安装服务时使用的账户
18                    
19                        WTSerInst = new ServiceInstaller();                        
20                        WTSerInst.StartType = ServiceStartMode.Automatic ; //启动服务的后模式(Automatic 自动,Manual 手动,Disabled 禁用)    
21                        WTSerInst.ServiceName = "WriteTextService";     //要安装服务的名称 与服务类名相同
22                        
23                        Installers. Add(WTSerInst);    //把服务安装类放入安装集合中
24                        Installers. Add(WTProInst);
25                }
26                /**////
27                /// 重写父类的安装,并在安装服务后写入服务的描述
28                ///

29                /// name="stateSaver">
30                 public override void Install(IDictionary stateSaver)
31                {
32                        RegistryKey system,service,config;
33                        try
34                        {
35                                base.Install(stateSaver);
36                                system = Registry.LocalMachine.OpenSubKey("System").OpenSubKey("CurrentControlSet").OpenSubKey("Services");
37                                service = system.OpenSubKey(this.WTSerInst.ServiceName, true);
38                                service.SetValue("Description", "……这是一个每秒写入 Text一次时间的服务……");                            
39                                config = service.CreateSubKey("AdditionalInformation");
40                        }
41                        catch
42                        { }
43                }
44                /**////
45                /// 重写父类的卸载,并在卸载服务后删除描述
46                ///

47                /// name="stateServer">
48                 public override void Uninstall(IDictionary stateServer)
49                {
50                        RegistryKey system,currentControlSet,services,service;
51                        try
52                        {
53                                system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
54                                currentControlSet = system.OpenSubKey("CurrentControlSet");
55                                services = currentControlSet.OpenSubKey("Services");
56                                service = services.OpenSubKey(this.WTSerInst.ServiceName, true);
57                                service.DeleteSubKeyTree("AdditionalInformation");
58                        }
59                        catch    
60                        {}
61                        finally
62                        {
63                                base.Uninstall(stateServer);
64                        }
65                }
66        }
67}
68
这样就完成了一个服务,关且有服务的描述,最要是通过重写父类 Install 和Uninstall 来完成对服务描述的添加。因为服务都是在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/WriteTextService 下有个项Description ,给这个项添加数据就对应该服务的描述,所以 Install 和Uninstall 两个方法本质上就是注册表英的添加与删除。
 
接下来我们看一下服务的操作,即装载,卸载,启动,停止。
我们新建一个web 网站,只有一个Default.aspx 页面,代码如下:
Default.aspx
 
1<%@ Page Language="C#" AutoEventWireup="true"    CodeFile=" Default.aspx.cs" Inherits="_Default" %>
2
3PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5
6
7        无标题页
8
9
10        

11        

12        
13                Text="装载服务" />
14                Text="卸载服务" />
15                Text="启动服务" />
16                Text="停止服务" />
17        
18        

19        

20
21
22
 
Default.aspx.cs
 
1using System;
2using System.Configuration;
3using System.Web;
4using System.Web.Security;
5using System.Web.UI;
6using System.Web.UI.HtmlControls;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Xml.Linq;
10using System.Configuration.Install;
11using System.Collections;
12using System.ServiceProcess;
13
14
15public partial class _Default : System.Web.UI.Page    
16{
17        protected void Page_Load(object sender, EventArgs e)
18        {
19
20        }
21        protected void Button1_Click(object sender, EventArgs e)
22        {
23                AssemblyInstaller myassemblyinstaller = new AssemblyInstaller();//加载一个程序集,并运行其中的所有安装程序。
24                myassemblyinstaller.UseNewContext = true;
25                myassemblyinstaller.Path = @"f:/gsw.exe";//服务所在的路径
26                Hashtable mysavedstate = new Hashtable();
27                myassemblyinstaller.Install(mysavedstate);
28                myassemblyinstaller. Commit(mysavedstate);
29                myassemblyinstaller.Dispose();
30                Response.Write("安装服务成功");
31        
32        }
33        protected void Button2_Click(object sender, EventArgs e)
34        {
35                AssemblyInstaller myassemblyinstaller = new AssemblyInstaller();
36                myassemblyinstaller.UseNewContext = true;
37                myassemblyinstaller.Path = @"f:/gsw.exe";//服务所在的路径
38                myassemblyinstaller.CommandLine = new string[1] { "/u" };// 利用/u命令来完成卸载
39                myassemblyinstaller.Uninstall( null);
40                myassemblyinstaller.Dispose();
41                Response.Write("卸载服务成功");
42        }
43        protected void Button3_Click(object sender, EventArgs e)
44        {
45                ServiceController sc = new ServiceController();//表示 Windows 服务并允许连接到正在运行或者已停止的服务、对其进行操作或获取有关它的信息。
46                sc.DisplayName = "桂素伟";
47                sc.ServiceName = "WriteTextService";
48                sc.Start();//启动这个名称的服务
49                System.Threading.Thread.Sleep(1000);
50                sc.Refresh();//刷新服务的状态
51                 if (sc.Status == ServiceControllerStatus.Running)//判断服务是已经运行
52                {
53                    Response .Write ("服务成功启动!");
54                }
55        }
56        protected void Button4_Click(object sender, EventArgs e)
57        {
58                ServiceController sc = new ServiceController();
59                sc.ServiceName = "WriteTextService";
60                sc.Stop();
61                
62                System.Threading.Thread.Sleep(1000);
63                sc.Refresh();//刷新服务的状态
64                 if (sc.Status == ServiceControllerStatus.Stopped)//判断服务是已经运行
65                {
66                     Response .Write ("服务成功停止!");
67                }
68        }
69}
70
 
我们是通过 AssemblyInstaller 类来完成对服务的装载和卸载,通过 ServiceController 类来完成对服务的启动和停止。
这样,我们就把服务和控制服务的代友做完整了。
(我的代码是在vista和vs2008下实现的。)