C# 实现windows 系统服务(全,含代码)

  •  Windows Service简介:

一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序。Windows服务程序虽然是可执行的,但是它不像一般的可执行文件通过双击就能开始运行了,它必须有特定的启动方式。这些启动方式包括了自动启动和手动启动两种。对于自动启动的Windows服务程序,它们在Windows启动或是重启之后用户登录之前就开始执行了。只要你将相应的Windows服务程序注册到服务控制管理器(Service Control Manager)中,并将其启动类别设为自动启动就行了。而对于手动启动的Windows服务程序,你可以通过命令行工具的NET START 命令来启动它,或是通过控制面板中管理工具下的服务一项来启动相应的Windows服务程序。

同样,一个Windows服务程序也不能像一般的应用程序那样被终止。因为Windows服务程序一般是没有用户界面的,所以你也要通过命令行工具或是下面图中的工具来停止它,或是在系统关闭时使得Windows服务程序自动停止。因为Windows服务程序没有用户界面,所以基于用户界面的API函数对其是没有多大的意义。为了能使一个Windows服务程序能够正常并有效的在系统环境下工作,程序员必须实现一系列的方法来完成其服务功能。Windows服务程序的应用范围很广,典型的Windows服务程序包含了硬件控制、应用程序监视、系统级应用、诊断、报告、Web和文件系统服务等功能。

和Windows服务程序相关的命名空间涉及到以下两个:System.ServiceProcess System.Diagnostics

实际编写方式,我就不写了,大家可以看下petercao的博文:http://www.cnblogs.com/bluestorm/p/3510398.html

  •  代码结构
  •  

  • ListenService :windows 服务的主体,实现了windows 服务代码、服务安装及卸载

  • ListenServiceUI: 我做了一个简易的登陆窗口,和服务操作界面,大家就不需要去services.msc 服务管理器 操作启动关闭服务了

  ListenService 中,DataMonitorService类是服务类,里面包含了服务的启动和停止,还有一个定时器,执行windows服务的定时操作

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Common;

namespace ListenService
{
    partial class DataMonitorService : ServiceBase
    {
        public DataMonitorService()
        {
            InitializeComponent();
        }

        private ListenDataClass sdc = new ListenDataClass();
        System.Timers.Timer timer1;//计时器
        protected override void OnStart(string[] args)
        {

            // 记录服务启动日志。
            LogTextHelper.Log("服务启动前准备.");
            LogTextHelper.Log("服务已经启动,启动时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss "));
            //线程 检查定时器
            if (timer1 == null)
            {
                LogTextHelper.Log("定时器null,开始初始化定时器");
                timer1 = new System.Timers.Timer();
                //设置定时间隔时间,默认60秒,
                int SecondCount = 60;
                //获取配置文件中的间隔时间,如果有将替换默认
                string sc = System.Configuration.ConfigurationManager.AppSettings["syncSecond"];
                if (!string.IsNullOrEmpty(sc) && ValidateUtil.IsNumber(sc))
                {
                    //将获取配置文件的定时间隔 记录下来   <add key="syncSecond" value="60"/>
                    SecondCount = Convert.ToInt32(sc);
                }
                //1000毫秒=1秒,与定时间隔 相乘,计算共多少毫秒
                timer1.Interval = 1000 * SecondCount;
                //绑定监听事件
                timer1.Elapsed += new System.Timers.ElapsedEventHandler(sdc.SynData);
                //启动定时器
                timer1.Enabled = true;
                LogTextHelper.Log("定时器初始化完成,定时器已经启动。");
            }
            else
            {
                timer1.Enabled = true;
                LogTextHelper.Log("定时器初始化完成,定时器已经启动。");
            }
        }

        protected override void OnStop()
        {
            //当服务结束时,结束定时器
            if (timer1 != null)
                timer1.Enabled = false;
            // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
            LogTextHelper.Log("服务已经结束,结束时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss "));
        }
    }
}

Install.bat 和Uninstall.bat 两个文件,分别是安装服务和卸载服务,这两个文件不需要我们手动操作,将在UI界面的程序中自动调用。

ListenServiceUI,里面分别有2个页面,一个是登陆,一个是操作

 

登陆界面

服务控制窗口

登陆名:admin,密码123456,程序中写死了,如果大家愿意,可以写入文件或数据库,我的例子,简单的一些更容易操作。

控制窗口可以安装、启动、停止和卸载服务。点Exit时,仅仅是关闭了ui,不会对程序进行处理。

后台管理代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
using System.IO;

namespace ListenServiceUI
{
    public partial class ServiceSetting : Form
    {
        public ServiceSetting()
        {
            InitializeComponent();
        }


        //安装服务
        private void btnInstallService_Click(object sender, EventArgs e)
        {
            ;
            ShowState("开始安装服务");
            try
            {
                string CurrentDirectory = System.Environment.CurrentDirectory;
                System.Environment.CurrentDirectory = CurrentDirectory + "\\Service";
                ShowState("查找服务目录");
                Process process = new Process();
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.FileName = "Install.bat";
                process.StartInfo.CreateNoWindow = true;
                process.Start();
                System.Environment.CurrentDirectory = CurrentDirectory;
                ShowState("服务安装完成。");
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                if (ex.InnerException != null)
                    msg += ex.InnerException.Message;
                ShowState("安装服务出现错误:" + msg);
            }
        }
        //卸载
        private void btnUninstallService_Click(object sender, EventArgs e)
        {
            ShowState("开始卸载服务");
            try
            {
                string CurrentDirectory = System.Environment.CurrentDirectory;
                System.Environment.CurrentDirectory = CurrentDirectory + "\\Service";
                Process process = new Process();
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.FileName = "Uninstall.bat";
                process.StartInfo.CreateNoWindow = true;
                process.Start();
                System.Environment.CurrentDirectory = CurrentDirectory;
                ShowState("服务卸载完成。");
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                if (ex.InnerException != null)
                    msg += ex.InnerException.Message;
                ShowState("卸载服务出现错误:" + msg);
            }
        }
        //启动
        private void btnStartService_Click(object sender, EventArgs e)
        {
            try
            {

                ShowState("启动服务开始");
                ServiceController serviceController = new ServiceController("DataMonitorService");
                serviceController.Start();
                ShowState("启动服务完成。");
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                if (ex.InnerException != null)
                    msg += ex.InnerException.Message;
                ShowState("启动服务出现错误:" + msg);
            }
        }
        //停止
        private void btnStopService_Click(object sender, EventArgs e)
        {
            try
            {

                ShowState("停止服务开始");
                ServiceController serviceController = new ServiceController("DataMonitorService");
                if (serviceController.CanStop)
                    serviceController.Stop();

                ShowState("停止服务完成。");
            }
            catch (Exception ex)
            {

                string msg = ex.Message;
                if (ex.InnerException != null)
                    msg += ex.InnerException.Message;
                ShowState("停止服务出现错误:" + msg);
            }
        }
        //查看状态
        private void btnShowState_Click(object sender, EventArgs e)
        {
            try
            {
                ServiceController serviceController = new ServiceController("DataMonitorService");
                string Status = serviceController.Status.ToString();
                ShowState("当前服务状态是:" + Status);
            }
            catch (Exception ex)
            {
                ShowState("查看状态出现错误:" + ex.Message);
            }
        }

        private void ShowState(string message)
        {
            textBox1.Text = message;
        }

        private void ServiceSetting_Load(object sender, EventArgs e)
        {
            string Installbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe {0}
Net Start DataMonitorService
sc config DataMonitorService start = auto";
            string directory = Path.Combine(System.Environment.CurrentDirectory, "Service");
            File.WriteAllText(Path .Combine(directory, "Install.bat"), string.Format(Installbat_content, Path.Combine(directory, "ListenService.exe")));
            string Unistallbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u {0}";

            File.WriteAllText(Path.Combine(directory, "Uninstall.bat"), string.Format(Unistallbat_content, Path.Combine(directory, "ListenService.exe")));


            this.Hide();
            Login login = new Login();
            if (login.ShowDialog() == DialogResult.OK)
            {
                myConfig.loginstate = 1;
                this.Show();
                ShowState("一切运行正常。");
            }
            else
            {
                this.Width = 1;
                this.Height = 1;
                this.StartPosition = FormStartPosition.CenterScreen;
                Application.Exit();
                return;
            }

        }

        private void btnExitApp_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

在使用UI时要注意的2个事项

1、启动ui时,必须使用管理员身份登陆,不然是没有权限对服务进行操作的

2、安装服务和卸载服务的bat批处理文件中,要写服务的绝对路径,如果写相对路径偶尔会出现问题。我这里在ServiceSetting.cs类中,通过程序进行了服务位置定位。

            string Installbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe {0}
Net Start DataMonitorService
sc config DataMonitorService start = auto";
            string directory = Path.Combine(System.Environment.CurrentDirectory, "Service");
            File.WriteAllText(Path .Combine(directory, "Install.bat"), string.Format(Installbat_content, Path.Combine(directory, "ListenService.exe")));
            string Unistallbat_content = @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u {0}";

            File.WriteAllText(Path.Combine(directory, "Uninstall.bat"), string.Format(Unistallbat_content, Path.Combine(directory, "ListenService.exe")));

配置文件中设定定时器 操作间隔

为了方便修改,将定时间隔放在了app.config中,

    <!--同步间隔,单位:秒-->
    <add key="syncSecond" value="60"/>

启动后效果:

登陆

操作界面

安装服务后

服务管理器中的服务(如果需要随机启动,请将手动设置为自动

设置自动启动

 代码下载地址:http://download.csdn.net/detail/l9861125/9594564

 

posted @ 2016-08-04 10:29  听风.  阅读(16688)  评论(0编辑  收藏  举报