Fork me on GitHub

.net知识和学习方法系列(二十五) .net中的windows service与服务操作

昨天一个朋友想用做个短信网关,与移动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        /// <summary>
27        /// 重写父类的安装,并在安装服务后写入服务的描述
28        /// </summary>
29        /// <param name="stateSaver"></param>

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        /// <summary>
45        /// 重写父类的卸载,并在卸载服务后删除描述
46        /// </summary>
47        /// <param name="stateServer"></param>

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
 3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4
 5<html xmlns="http://www.w3.org/1999/xhtml">
 6<head runat="server">
 7    <title>无标题页</title>
 8</head>
 9<body>
10    <form id="form1" runat="server">
11    <div>
12    
13        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="装载服务" />
14        <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="卸载服务" />
15        <asp:Button ID="Button3" runat="server" onclick="Button3_Click" Text="启动服务" />
16        <asp:Button ID="Button4" runat="server" onclick="Button4_Click" Text="停止服务" />
17    
18    </div>
19    </form>
20</body>
21</html>
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下实现的。)

posted @ 2008-12-26 10:54  桂素伟  阅读(965)  评论(0编辑  收藏  举报