如何更简洁、方便的注册 windows 服务,并对服务的声明周期进行有效管理?C# Windows 服务程序,提供了一种很好的手段。可以通过写一个 C# Windows 服务代理程序,将其注册为 Windows 服务,然后在内部再调用其他程...

如何更简洁、方便的注册 windows 服务,并对服务的声明周期进行有效管理?C# Windows 服务程序,提供了一种很好的手段。
可以通过写一个 C# Windows 服务代理程序,将其注册为 Windows 服务,然后在内部再调用其他程序,比如 Java 程序。
使用 VisualStudio 创建 C# Windows 服务程序
详细步骤,网上有很多,也很简单。
Service1.cs
服务程序的主要逻辑:
- 服务启动后,读取服务程序当前目录下的 start.bat 文件内容,然后调用 Process 启动目标程序。
- 在新线程中,等待目标程序结束;
- 创建一个周期性的任务,往服务日志中写消息;
- 当目标程序退出时,使用本服务的 ServiceController 实例,将服务关闭。
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 System.IO;
namespace BTCI
{
public partial class Service1 : ServiceBase
{
System.Diagnostics.Process p;
System.Threading.Timer recordTimer;
Thread starter;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
IntialLogger(); // 启动程序后,启动监控日志
log(DateTime.Now.ToString() + " [info] start service");
starter = new Thread(startProcess);
starter.Start();
//startProcess();
return;
}
private void startProcess()
{
string cmd;
log(DateTime.Now.ToString() + " [info] start sub process");
log(DateTime.Now.ToString() + " [info] current directory = " + Directory.GetCurrentDirectory());
try
{
using (StreamReader sr = new StreamReader("start.bat"))
{
cmd = sr.ReadLine();
}
log(DateTime.Now.ToString() + " [info] start.bat content = " + cmd);
if (String.IsNullOrEmpty(cmd))
{
log(DateTime.Now.ToString() + " [error] cmd is null");
return;
}
p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true; //接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = true; //由调用程序获取输出信息
p.StartInfo.RedirectStandardError = true; //重定向标准错误输出
p.StartInfo.CreateNoWindow = true; //不显示程序窗口
log(DateTime.Now.ToString() + " [info] process started");
p.Start();//启动程序
//向cmd窗口发送输入信息
p.StandardInput.WriteLine(cmd + "&exit");
p.StandardInput.AutoFlush = true;
p.WaitForExit();//等待程序执行完退出进程
log(DateTime.Now.ToString() + " [info] process exit");
p.Close();
releaseTimer();
}
catch (Exception e)
{
// 向用户显示出错消息
log(DateTime.Now.ToString() + " [error] start sub process failed; "+e.Message);
return;
}
}
protected override void OnStop()
{
log(DateTime.Now.ToString() + " [info] stop service ");
releaseTimer();
}
private void IntialLogger()
{
TimerCallback timerCallback = new TimerCallback(CallbackTask);
AutoResetEvent autoEvent = new AutoResetEvent(false);
recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 6000);
}
private void releaseTimer()
{
if (recordTimer != null)
{
log(string.Format(@"{0} [info] release timer", DateTime.Now));
recordTimer.Dispose();
}
log(string.Format(@"{0} [info] service exit", DateTime.Now));
ServiceController sc = new ServiceController("TargetServiceName");// 这里一定要与服务名称一致!不是显示名称!
if (sc.Status.Equals(ServiceControllerStatus.Running))
{
sc.Stop();
sc.Refresh();
}
}
private void CallbackTask(Object stateInfo)
{
//log(string.Format(@"{0} [info] service running", DateTime.Now));
if (starter.IsAlive)
{
log(string.Format(@"{0} [info] service running", DateTime.Now));
}
else
{
log(string.Format(@"{0} [error] thread is not alive", DateTime.Now));
releaseTimer();
}
}
private static void log(string content)
{
if (string.IsNullOrEmpty(content))
{
return;
}
try
{
string logFile = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, string.Format("service.{0:yyyyMMdd}.log", DateTime.Now));
using (FileStream fileStream = new FileStream(logFile, FileMode.Append, FileAccess.Write))
{
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
streamWriter.WriteLine(content);
}
}
}
catch { }
}
}
}
织梦狗教程
本文标题为:C# Windows 服务


基础教程推荐
猜你喜欢
- c#中WinForm用OpencvSharp实现ROI区域提取的示例 2023-06-04
- 浅谈C#数组(二) 2023-05-05
- C#实现插入排序 2023-06-28
- 详解c# 强制转换和类型转换 2023-03-13
- C#类继承中构造函数的执行序列示例详解 2022-12-31
- 深入理解C#管道式编程 2023-04-21
- C# API中模型与它们的接口设计详解 2022-12-26
- C# WinForm实现自动更新程序之客户端的示例代码 2023-07-05
- c# – 线程已退出,Windows窗体中的代码为0 2023-09-19
- c# – MySQL“与SQL Server建立连接时发生与网络相关或特定于实例的错误” 2023-11-09