设为首页 收藏本站
查看: 881|回复: 0

[经验分享] C# 实现windows 系统服务(全,含代码)

[复制链接]

尚未签到

发表于 2017-6-28 17:51:05 | 显示全部楼层 |阅读模式

  • 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


  • 代码结构
  • DSC0000.png
  •   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个页面,一个是登陆,一个是操作
   DSC0001.png
  登陆界面
DSC0002.png

  服务控制窗口
  登陆名: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"/>
  启动后效果:
DSC0003.png

  登陆
DSC0004.png

  操作界面
DSC0005.png

  安装服务后
DSC0006.png

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

  设置自动启动
  代码下载地址:http://download.csdn.net/detail/l9861125/9594564

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-389075-1-1.html 上篇帖子: Env:Gvim开发环境配置笔记--Windows篇 下篇帖子: Windows下安装ElasticSearch 5.0.0
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表