隐藏

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

发布:2018/7/2 20:17:27作者:管理员 来源:本站 浏览次数:1139

  •  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