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