winsvc

1.0.1 • Public • Published

winsvc

一个专门用来在Windows系统上以服务方式运行NodeJS脚本的工具。 A tool designed to run NodeJS scripts in service mode on Windows system.

安装(Installation)

npm install -g winsvc

用法(Usage)

安装服务(Install Service)

winsvc -i ServiceName ScriptPath

卸载服务(Uninstall Service)

winsvc -u ServiceName

日志文件deamon.log将会在ScriptPath目录中生成。 The log file deamon.log will be generated in the scriptpath directory.

bin文件源码(Bin File Source)

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace winsvc
{
    partial class WinSvc : ServiceBase
    {
        string fullPath = string.Empty;
        string directory = string.Empty;
        string logFile = string.Empty;
        string[] args;

        Process process = null;
        private bool running = false;
        private object locker = new object();

        public WinSvc(string[] args)
        {
            InitializeComponent();
            this.args = args;
            if (args.Length > 0) fullPath = string.Join(" ", args);
            directory = Path.GetDirectoryName(fullPath);
            string file = Path.GetFileName(fullPath);
            if (!File.Exists(fullPath)) throw new Exception("目标文件不存在");
            logFile = Path.Combine(directory, "deamon.log");
        }

        protected override void OnStart(string[] args)
        {
            Start();
        }

        protected override void OnStop()
        {
            if (process != null && !process.HasExited)
            {
                RunCmd("taskkill /F /PID " + process.Id + " /T");
            }
            if (running)
            {
                running = false;
                WriteLine("Service Stopping");
            }
            else
            {
                WriteLine("Service Stopped");
            }
        }

        public void Start()
        {
            running = true;
            WriteLine("Service Start");
            new Thread(Run).Start();
        }

        private void Run()
        {
            while (running)
            {
                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.WorkingDirectory = directory;
                    startInfo.FileName = "node.exe";
                    startInfo.UseShellExecute = false;
                    startInfo.CreateNoWindow = true;
                    startInfo.RedirectStandardOutput = true;
                    startInfo.RedirectStandardError = true;
                    startInfo.StandardOutputEncoding = Encoding.UTF8;
                    startInfo.StandardErrorEncoding = Encoding.UTF8;
                    startInfo.Arguments = string.Join(" ", args);
                    process = Process.Start(startInfo);
                    process.OutputDataReceived += (s, e) =>
                    {
                        if (!string.IsNullOrEmpty(e.Data)) { WriteLine(e.Data); }
                    };
                    process.ErrorDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { WriteLine(e.Data); } };
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();
                    WriteLine("Process Start {0}", process.Id);
                    while (running)
                    {
                        if (process.HasExited)
                        {
                            WriteLine("Process Exit {0}", process.Id);
                            break;
                        }
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception e)
                {
                    WriteLine(e);
                }
            }
            Stop();
        }

        private void RunCmd(string command)
        {
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/c " + command;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.Start();
            process.OutputDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { WriteLine(e.Data); } };
            process.ErrorDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { WriteLine(e.Data); } };
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
        }

        private void WriteLine(Exception e)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(e.Message);
            string[] stackTraces = e.StackTrace.Split('\n');
            for (int i = 0; i < stackTraces.Length; i++)
            {
                if (stackTraces[i].Contains("winsvc"))
                {
                    sb.Append("\r\n" + stackTraces[i].Trim());
                    break;
                }
            }
            WriteLine(sb.ToString());
        }

        private void WriteLine(string format, params object[] args)
        {
            WriteLine(string.Format(format, args));
        }

        private void WriteLine(string msg)
        {
            lock (locker)
            {
                StreamWriter sw = null;
                try
                {
                    string message = string.Format("[{0}] {1}", DateTime.Now.ToString("MM/dd HH:mm:ss.fff"), msg);
                    Debug.WriteLine(message);
                    sw = new StreamWriter(logFile, true);
                    sw.WriteLine(message);
                    FileInfo fileinfo = new FileInfo(logFile);
                    if (fileinfo.Length > 2097152)
                    {
                        sw.Close();
                        string all = File.ReadAllText(logFile);
                        string[] lines = all.Split('\n');
                        int size = Convert.ToInt32(lines.Length / 2);
                        string[] linesNew = lines.Skip(size).ToArray();
                        File.Delete(logFile);
                        File.WriteAllText(logFile, string.Join("\n", linesNew));
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                }
                finally
                {
                    if (sw != null)
                    {
                        sw.Close();
                    }
                }
            }
        }
    }
}

问题反馈(Feedback)

lzh@linzihua.com

Readme

Keywords

Package Sidebar

Install

npm i winsvc

Weekly Downloads

2

Version

1.0.1

License

ISC

Unpacked Size

18.2 kB

Total Files

4

Last publish

Collaborators

  • linzihua