如何更简洁、方便的注册 windows 服务,并对服务的声明周期进行有效管理?C# Windows 服务程序,提供了一种很好的手段。

可以通过写一个 C# Windows 服务代理程序,将其注册为 Windows 服务,然后在内部再调用其他程序,比如 Java 程序。

使用 VisualStudio 创建 C# Windows 服务程序

在这里插入图片描述

详细步骤,网上有很多,也很简单。


Service1.cs

服务程序的主要逻辑:

  1. 服务启动后,读取服务程序当前目录下的 start.bat 文件内容,然后调用 Process 启动目标程序。
  2. 在新线程中,等待目标程序结束;
  3. 创建一个周期性的任务,往服务日志中写消息;
  4. 当目标程序退出时,使用本服务的 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 { }
        }
    }
}

标签: Windows, log, C#, 服务, string, System, using, Now, DateTime

相关文章推荐

添加新评论,含*的栏目为必填