windows 服务
Windows服务简单开发
一、服务项目搭建
1. 新建一个Windows服务项目
1.1建立一个WindowsService项目


1.2添加一个服务后台管理类库,便于项目维护

2. 定时任务服务的一般通用模版
using DemoService.Management; using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; using System.Timers; namespace DemoService { public partial class TestService : ServiceBase { public TestService() { InitializeComponent(); } Timer timer = null; /// <summary> /// 定义服务是否正在运行状态 /// </summary> private static bool IsExec = false; /// <summary> /// 服务启动时执行的代码 /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { // TODO: 在此处添加代码以启动服务。 timer = new Timer(1000 * 60) { AutoReset = true, Enabled = true }; //间隔1分钟 timer.Elapsed += timer_Elapsed; } void timer_Elapsed(object sender, ElapsedEventArgs e) { LogHelper.WriteLog("TestServiceStart....."); timer.Start(); //执行定时任务 var interval_time = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalTime"] ?? "1"); if (DateTime.Now.Minute % interval_time == 0 && !IsExec)//每隔3分钟执行一次 //if (DateTime.Now.Hour==0 && DateTime.Now.Minute == 0 && !IsExec)//每天0点0分执行 { try { IsExec = true; //业务代码 //DoSomething(); //测试代码 DemoService.Management.clsDemoService _clsDemoService = new Management.clsDemoService(); string sResult = _clsDemoService.Test(interval_time.ToString()); LogHelper.WriteLog("TestServiceOver,response:" + sResult); } catch (Exception ex) { //抛出错误或者打印日志,注意:如果catch到异常服务会卡住(因为IsExec值为true不再改变),可根据自己业务需要是否加finally处理 LogHelper.WriteLog("TestServiceError", ex.Message); } finally { IsExec = false; } IsExec = false; } } /// <summary> /// 服务停止时执行的代码 /// </summary> protected override void OnStop() { timer.Stop(); LogHelper.WriteLog("TestServiceStop"); } /// <summary> /// 服务暂停时执行的代码 /// </summary> protected override void OnPause() { LogHelper.WriteLog("TestServicePause"); } /// <summary> /// 服务恢复时执行的代码 /// </summary> protected override void OnContinue() { LogHelper.WriteLog("TestServiceContinue"); } } }
二、Windows服务的部署
1. 定义服务的名称和描述,以及服务的运行账户
在服务的设计模式视图中“右键→添加安装程序”,会自动添加一个安装程序文件,名称为ProjectInstaller.cs

在ProjectInstaller.cs的设计视图中,serviceInstaller控制服务的名称描述等相关内容,serviceProcessInstaller控制服务运行的账户。
(1) serviceInstaller属性配置
右键serviceInstaller1→属性

注意
ServiceName和DisplayName 要保持一致,不然在安装时安装失败
ServiceName:服务名称,简单来说就是服务在操作系统中的名称,即系统任务管理器中该服务的进程名称。
DisplayName:展示名称,说明见下图
Description:服务描述说明,说明见下图
DisplayName和Description
使用Win+R,输入services.msc,打开系统的服务管理器

(2) serviceProcessInstaller属性配置
右键serviceProcessInstaller1→属性

需要重点关注的就一个Account属性,改属性默认值是User(这里是个坑,因为选择为User的服务在启动时需要输入账户用户名和密码),这里调整为LocalService即可。
2. 服务的安装
windows服务的安装需要使用到InstallUtil.exe,这个文件路径如下,
InstallUtil.exe(x86) C:\Windows\Microsoft.NET\Framework\v4.0.30319
InstallUtil.exe(x64) C:\Windows\Microsoft.NET\Framework64\v4.0.30319
使用x86安装还是x64安装取决与项目配置,右键项目,选择属性

可将InstallUtil.exe拷贝到项目中里面
再新建两个2个bat【Install.bat、Uninstall.bat】文件用于安装和卸载服务,也拷贝到项目中去

Install.bat
%~dp0InstallUtil.exe %~dp0项目名称.exe
Net Start 服务名称
sc config 服务名称 start= auto
pause
Uninstall.bat
%~dp0InstallUtil /u %~dp0项目名称.exe
pause
项目名称:该WinService服务项目的名称
服务名称:是serviceInstaller1中配置的ServiceName
把这3个文件粘贴到项目中以后,选中,右键属性

右键项目,生成,然后到项目目录下的打开bin文件夹,根据生成方式,选择Debug/Release文件夹

将Debug整个文件拷贝到服务器。执行Install.bat即可进行安装
注意,win2008及以上系统,执行安装卸载bat需要管理员权限运行:即右键Install.bat/Uninstall.bat→以管理员身份运行。
三、调试Windows服务
调试Windows服务,可以采用将服务附加到进程的方法。
1、在菜单栏选项里面选择调试-->附加到进程

2、在附加到进程界面,选择相应的服务进程(DemoService.exe),点击附加。

注意要把服务附加到进程,必须保证服务是启动状态,否则在进程里面看不到服务的进程。
四、总结
1、Windows服务调试不能直接F5,可以通过附加到进程方式调试(调试前提:将服务启动、以管理员身份运行VS)
2、Windows服务由于没有直接的用户交互,服务的状态必须通过日志才可知晓,恰当的加入try catch
3、所有可能发生变化的内容都不要写死,尽量通过配置文件来实现,实现项目的灵活性
4、Windows服务多用于定时操作、大数据量操作、监控操作等应用场景
五、常见问题
1.写Windows服务的时候,运行了一下,就是没反应,命令框一闪而过,查了一下异常,大致是题目的那样。原因是因为权限不足。但是在网上搜的方法都不顶用。
解决方法步骤如下:
(1)以管理员身份运行CMD;
(2)而后将CMD中的路径调整到bat文件所在路径下,比如路径为“D:\Debug”。cd /d d:\Test【具体目录】
(3)而后在CMD中输入“install.bat”即可正确安装。

浙公网安备 33010602011771号