• .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下实现的。)

    ****欢迎关注我的asp.net core系统课程****
    《asp.net core精要讲解》 https://ke.qq.com/course/265696
    《asp.net core 3.0》 https://ke.qq.com/course/437517
    《asp.net core项目实战》 https://ke.qq.com/course/291868
    《基于.net core微服务》 https://ke.qq.com/course/299524
  • 相关阅读:
    软件测试基础知识 + 面试理论(超详细)
    Qt 信号槽连接不成功问题原因汇总
    白平衡进化史
    Qt QPlainTextEdit多行文本编辑器
    C/C++变量命名规则
    win10 计算机管理员权限粘贴文件,高手分析win10往c盘粘贴文件需要权限的详细解决对策...
    常见的二十种软件测试方法详解(史上最全)
    C/C++ 回车符“0x0D”、“\n”,换行符“0x0A”、“\r
    C/C++ x86 x64下调用约定浅析
    C++ 命名规范
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/1362797.html
Copyright © 2020-2023  润新知