Windows服务简单开发
一、服务项目搭建
1、 新建一个Windows服务项目
1.1、建立一个WindowsService项目
1.2、添加一个服务后台管理类库,便于项目维护
2、定时任务服务的一般通用模版
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();
}
/// <summary>
/// 服务启动时执行的代码
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
Timer timer = new Timer(1000 * 60) { AutoReset = true, Enabled = true }; //间隔1分钟
timer.Elapsed += timer_Elapsed;
timer.Start();
}
/// <summary>
/// 定义服务是否正在运行状态
/// </summary>
private static bool IsExec = false;
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//执行定时任务
var interval_time = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalTime"] ?? "3");
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();
//测试代码
LogHelper.WriteLog("OnStart", DateTime.Now + "服务开始。。。");
DemoService.Management.clsDemoService _clsDemoService = new Management.clsDemoService();
LogHelper.WriteLog("OnStartOver", DateTime.Now + _clsDemoService.Test(Convert.ToInt32(interval_time)));
}
catch (Exception ex)
{
//抛出错误或者打印日志,注意:如果catch到异常服务会卡住(因为IsExec值为true不再改变),可根据自己业务需要是否加finally处理
LogHelper.WriteLog("Error", DateTime.Now + ex.Message);
}
finally
{
IsExec = false;
}
IsExec = false;
}
}
/// <summary>
/// 服务停止时执行的代码
/// </summary>
protected override void OnStop()
{
LogHelper.WriteLog("OnStop", DateTime.Now + "服务停止");
}
/// <summary>
/// 服务暂停时执行的代码
/// </summary>
protected override void OnPause()
{
LogHelper.WriteLog("OnPause", DateTime.Now + "服务暂停");
}
/// <summary>
/// 服务恢复时执行的代码
/// </summary>
protected override void OnContinue()
{
LogHelper.WriteLog("OnContinue", DateTime.Now + "服务恢复");
}
}
}
二、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”即可正确安装。
源代码:
https://pan.baidu/s/1eEXvyHjiQ74dR84bpRMcLg
提取码 :629k