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();
}
}
}
}
}
}