C#/.Net Windows Service 定时服务
1.发现问题
发现公司之前的定时任务都是控制台,并且服务器上开了好几个控制台程序,就想把他们放在一个服务里面且各自按原来的周期定期执行
2.解决问题
2.1创建控制台程序
2.2创建完成添加windows Services
选中项目-->右键--->添加-->新建项
创建完成点击切换到代码视图,可以看到下代码,顾名思义,OnStart是启动时执行,OnStop服务停止时执行的
点击查看代码
partial class WinService : ServiceBase
{
public WinService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
}
protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
}
}
2.3添加ServiceHelper辅助类
点击查看代码
using System;
using System.Collections;
using System.Configuration.Install;
using System.Reflection;
using System.ServiceProcess;
namespace WindowsServiceDemo
{
public class ServiceHelper
{
/// <summary>
/// 服务是否存在
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
public static bool IsServiceExisted(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController s in services)
{
if (s.ServiceName == serviceName)
{
return true;
}
}
return false;
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="serviceName"></param>
public static void StartService(string serviceName)
{
if (IsServiceExisted(serviceName))
{
ServiceController service = new ServiceController(serviceName);
if (service.Status != ServiceControllerStatus.Running &&
service.Status != ServiceControllerStatus.StartPending)
{
service.Start();
for (int i = 0; i < 60; i++)
{
service.Refresh();
System.Threading.Thread.Sleep(1000);
if (service.Status == ServiceControllerStatus.Running)
{
break;
}
if (i == 59)
{
throw new Exception("Start Service Error:" + serviceName);
}
}
}
}
}
/// <summary>
/// 停止服务
/// </summary>
/// <param name="serviceName"></param>
public static void StopService(string serviceName)
{
if (IsServiceExisted(serviceName))
{
ServiceController service = new ServiceController(serviceName);
if (service.Status != ServiceControllerStatus.Stopped &&
service.Status != ServiceControllerStatus.StopPending)
{
service.Stop();
for (int i = 0; i < 60; i++)
{
service.Refresh();
System.Threading.Thread.Sleep(1000);
if (service.Status == ServiceControllerStatus.Stopped)
{
break;
}
if (i == 59)
{
throw new Exception("Start Service Error:" + serviceName);
}
}
}
}
}
/// <summary>
/// 获取服务状态
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
public static ServiceControllerStatus GetServiceStatus(string serviceName)
{
ServiceController service = new ServiceController(serviceName);
return service.Status;
}
/// <summary>
/// 安装配置服务
/// </summary>
/// <param name="serviceName"></param>
/// <param name="install"></param>
public static void ConfigService(string serviceName, bool install, string serviceDes = "")
{
TransactedInstaller ti = new TransactedInstaller();
ti.Installers.Add(new ServiceProcessInstaller
{
Account = ServiceAccount.LocalSystem
});
ti.Installers.Add(new ServiceInstaller
{
DisplayName = serviceName,
ServiceName = serviceName,
Description = serviceDes == "" ? "本地注册自主运行服务" : serviceDes,
ServicesDependedOn = new string[] { "MSSQLSERVER" },//前置服务
StartType = ServiceStartMode.Automatic//运行方式
});
ti.Context = new InstallContext();
ti.Context.Parameters["assemblypath"] = "\"" + Assembly.GetEntryAssembly().Location + "\" /service";
if (install)
{
ti.Install(new Hashtable());
}
else
{
ti.Uninstall(null);
}
}
}
}
2.4控制台程序Program
点击查看代码
class Program
{
static void Main(string[] args)
{
///带参启动运行服务
if (args.Length > 0)
{
try
{
ServiceBase[] serviceToRun = new ServiceBase[] { new WinService() };
ServiceBase.Run(serviceToRun);
}
catch (Exception ex)
{
System.IO.File.AppendAllText(@"D:\Log.txt", "\nService Start Error:" + DateTime.Now.ToString() + "\n" + ex.Message);
}
}
//不带参启动配置程序
else
{
titlelable:
Console.WriteLine("请输入服务名称");
string serviceName = Console.ReadLine();
if (string.IsNullOrEmpty(serviceName))
goto titlelable;
Console.WriteLine("请输入服务描述");
string serviceDes = Console.ReadLine();
StartLable:
Console.WriteLine("\n\n请选择你要执行的操作——1:自动部署服务,2:安装服务,3:卸载服务,4:停止服务,5:验证服务状态,6.退出");
Console.WriteLine("————————————————————");
ConsoleKey key = Console.ReadKey().Key;
//安装并且启动服务(如果当前服务存在,会卸载当前服务,然后再进行安装并启动)
if (key == ConsoleKey.NumPad1 || key == ConsoleKey.D1)
{
if (ServiceHelper.IsServiceExisted(serviceName))
{
ServiceHelper.ConfigService(serviceName, false, serviceDes);
}
if (!ServiceHelper.IsServiceExisted(serviceName))
{
ServiceHelper.ConfigService(serviceName, true, serviceDes);
}
ServiceHelper.StartService(serviceName);
goto StartLable;
}
else if (key == ConsoleKey.NumPad2 || key == ConsoleKey.D2)
{
if (!ServiceHelper.IsServiceExisted(serviceName))
{
ServiceHelper.ConfigService(serviceName, true, serviceDes);
}
else
{
Console.WriteLine("\n服务已存在......");
}
goto StartLable;
}
else if (key == ConsoleKey.NumPad3 || key == ConsoleKey.D3)
{
if (ServiceHelper.IsServiceExisted(serviceName))
{
ServiceHelper.ConfigService(serviceName, false);
}
else
{
Console.WriteLine("\n服务不存在......");
}
goto StartLable;
}
else if (key == ConsoleKey.NumPad4 || key == ConsoleKey.D4)
{
if (!ServiceHelper.IsServiceExisted(serviceName))
{
Console.WriteLine("\n服务不存在......");
}
else
{
ServiceHelper.StopService(serviceName);
Console.WriteLine("\n服务已停止,状态:" + ServiceHelper.GetServiceStatus(serviceName).ToString());
}
goto StartLable;
}
else if (key == ConsoleKey.NumPad5 || key == ConsoleKey.D5)
{
if (!ServiceHelper.IsServiceExisted(serviceName))
{
Console.WriteLine("\n服务不存在......");
}
else
{
Console.WriteLine("\n服务状态:" + ServiceHelper.GetServiceStatus(serviceName).ToString());
}
goto StartLable;
}
else if (key == ConsoleKey.NumPad6 || key == ConsoleKey.D6) { }
else
{
Console.WriteLine("\n请输入一个有效键!");
Console.WriteLine("————————————————————");
goto StartLable;
}
}
}
}
2.5添加定时任务
此处我们需要使用 定时器 System.Timers.Timer,使任务定时执行
点击查看代码
partial class WinService : ServiceBase
{
Timer timer = new Timer();
Timer timer1 = new Timer();
public WinService()
{
InitializeComponent();
}
/// <summary>
/// 服务启动
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
//定时服务
timer.Elapsed += new ElapsedEventHandler(TaskOne);
timer.AutoReset = true;//是否触发Elapsed事件
timer.Enabled = true;//每到指定时间Elapsed事件是触发一次(false),还是一直触发(true)
timer.Interval = GetConfig("TaskOne");////执行间隔时间,单位为毫秒
timer1.Elapsed += new ElapsedEventHandler(TaskTwo);
timer1.AutoReset = true;
timer1.Enabled = true;
timer1.Interval = GetConfig("TaskTwo");//;
}
/// <summary>
/// 服务停止
/// </summary>
protected override void OnStop()
{
File.AppendAllText(@"D:\ServiceLog.txt", " 服务已经停止:" + DateTime.Now.ToString());
}
/// <summary>
/// 业务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void TaskOne(object sender, ElapsedEventArgs e)
{
//业务处理
File.AppendAllText(@"D:\TaskOne.txt", " Service Start:" + DateTime.Now.ToString());
}
public void TaskTwo(object sender, ElapsedEventArgs e)
{
//业务处理
File.AppendAllText(@"D:\TaskTwo.txt", " Service Start:" + DateTime.Now.ToString());
}
/// <summary>
/// 获取配置文件
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static double GetConfig(string key)
{
var value = ConfigurationManager.AppSettings[key];
var v = string.IsNullOrEmpty(value) ? "1000" : value;
return Convert.ToDouble(value);
}
}
2.6启动控制台
启动控制台,按步骤注册
服务安装成功
配置文件我配置了两个任务的间隔时间为 5秒与10秒
任务执行情况,可以看到D盘生成两个文件,执行周期与配置时间相同
参考文档 C#代码安装服务
无穷的伟大,也是从“0”开始的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~