mirror of https://github.com/winsw/winsw
Support for startargument and stopargument to enable services that require something like 'catalina.bat run' and 'catalina stop'
git-svn-id: https://svn.kenai.com/svn/winsw~subversion/trunk@14 c8b2a3fe-9b5b-6a51-a37e-dc31b0e308faremotes/git-svn
parent
d9014f5db9
commit
afab25eba5
176
Main.cs
176
Main.cs
|
|
@ -86,26 +86,77 @@ namespace winsw
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
XmlNode argumentNode = dom.SelectSingleNode("//argument");
|
string arguments = AppendTags("argument");
|
||||||
|
|
||||||
if (argumentNode == null)
|
if (arguments == null)
|
||||||
{
|
{
|
||||||
return SingleElement("arguments");
|
var tagName = "arguments";
|
||||||
|
var argumentsNode = dom.SelectSingleNode("//" + tagName);
|
||||||
|
|
||||||
|
if (argumentsNode == null)
|
||||||
|
{
|
||||||
|
if (AppendTags("startargument") == null)
|
||||||
|
{
|
||||||
|
throw new InvalidDataException("<" + tagName + "> is missing in configuration XML");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string arguments = "";
|
return arguments;
|
||||||
|
|
||||||
foreach (XmlNode argument in dom.SelectNodes("//argument"))
|
|
||||||
{
|
|
||||||
arguments += " " + argument.InnerText;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Environment.ExpandEnvironmentVariables(arguments);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Multiple optional startargument elements.
|
||||||
|
/// </summary>
|
||||||
|
public string Startarguments
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return AppendTags("startargument");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Multiple optional stopargument elements.
|
||||||
|
/// </summary>
|
||||||
|
public string Stoparguments
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return AppendTags("stopargument");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string AppendTags(string tagName)
|
||||||
|
{
|
||||||
|
XmlNode argumentNode = dom.SelectSingleNode("//" + tagName);
|
||||||
|
|
||||||
|
if (argumentNode == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string arguments = "";
|
||||||
|
|
||||||
|
foreach (XmlNode argument in dom.SelectNodes("//" + tagName))
|
||||||
|
{
|
||||||
|
arguments += " " + argument.InnerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Environment.ExpandEnvironmentVariables(arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LogDirectory is the service wrapper executable directory or the optionally specified logpath element.
|
/// LogDirectory is the service wrapper executable directory or the optionally specified logpath element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -224,6 +275,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
private Process process = new Process();
|
private Process process = new Process();
|
||||||
private ServiceDescriptor descriptor;
|
private ServiceDescriptor descriptor;
|
||||||
|
private Dictionary<string, string> envs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates to the watch dog thread that we are going to terminate the process,
|
/// Indicates to the watch dog thread that we are going to terminate the process,
|
||||||
|
|
@ -340,7 +392,7 @@ namespace winsw
|
||||||
|
|
||||||
protected override void OnStart(string[] args)
|
protected override void OnStart(string[] args)
|
||||||
{
|
{
|
||||||
var envs = descriptor.EnvironmentVariables;
|
envs = descriptor.EnvironmentVariables;
|
||||||
foreach (string key in envs.Keys)
|
foreach (string key in envs.Keys)
|
||||||
{
|
{
|
||||||
EventLog.WriteEntry("envar " + key + '=' + envs[key]);
|
EventLog.WriteEntry("envar " + key + '=' + envs[key]);
|
||||||
|
|
@ -348,11 +400,57 @@ namespace winsw
|
||||||
|
|
||||||
HandleFileCopies();
|
HandleFileCopies();
|
||||||
|
|
||||||
EventLog.WriteEntry("Starting "+descriptor.Executable+' '+descriptor.Arguments);
|
string startarguments = descriptor.Startarguments;
|
||||||
|
|
||||||
|
if (startarguments == null)
|
||||||
|
{
|
||||||
|
startarguments = descriptor.Arguments;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startarguments += " " + descriptor.Arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLog.WriteEntry("Starting " + descriptor.Executable + ' ' + startarguments);
|
||||||
|
|
||||||
|
StartProcess(process, startarguments);
|
||||||
|
|
||||||
|
// send stdout and stderr to its respective output file.
|
||||||
|
HandleLogfiles();
|
||||||
|
|
||||||
|
process.StandardInput.Close(); // nothing for you to read!
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStop()
|
||||||
|
{
|
||||||
|
string stoparguments = descriptor.Stoparguments;
|
||||||
|
EventLog.WriteEntry("Stopping " + descriptor.Id);
|
||||||
|
orderlyShutdown = true;
|
||||||
|
|
||||||
|
if (stoparguments == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
// already terminated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stoparguments += " " + descriptor.Arguments;
|
||||||
|
|
||||||
|
StartProcess(new Process(), stoparguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartProcess(Process process, string arguments)
|
||||||
|
{
|
||||||
var ps = process.StartInfo;
|
var ps = process.StartInfo;
|
||||||
ps.FileName = descriptor.Executable;
|
ps.FileName = descriptor.Executable;
|
||||||
ps.Arguments = descriptor.Arguments;
|
ps.Arguments = arguments;
|
||||||
ps.CreateNoWindow = false;
|
ps.CreateNoWindow = false;
|
||||||
ps.UseShellExecute = false;
|
ps.UseShellExecute = false;
|
||||||
ps.RedirectStandardInput = true; // this creates a pipe for stdin to the new process, instead of having it inherit our stdin.
|
ps.RedirectStandardInput = true; // this creates a pipe for stdin to the new process, instead of having it inherit our stdin.
|
||||||
|
|
@ -364,40 +462,40 @@ namespace winsw
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
|
|
||||||
// send stdout and stderr to its respective output file.
|
|
||||||
HandleLogfiles();
|
|
||||||
|
|
||||||
// monitor the completion of the process
|
// monitor the completion of the process
|
||||||
new Thread(delegate()
|
new Thread(delegate()
|
||||||
{
|
{
|
||||||
|
string msg = process.Id + " - " + process.StartInfo.FileName + " " + process.StartInfo.Arguments;
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
if (!orderlyShutdown)
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
EventLog.WriteEntry("Child process terminated with " + process.ExitCode,EventLogEntryType.Warning);
|
if (orderlyShutdown)
|
||||||
Environment.Exit(process.ExitCode);
|
{
|
||||||
|
EventLog.WriteEntry("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Information);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EventLog.WriteEntry("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Warning);
|
||||||
|
Environment.Exit(process.ExitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ioe)
|
||||||
|
{
|
||||||
|
EventLog.WriteEntry("WaitForExit " + ioe.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
process.Dispose();
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ioe)
|
||||||
|
{
|
||||||
|
EventLog.WriteEntry("Dispose " + ioe.Message);
|
||||||
}
|
}
|
||||||
}).Start();
|
}).Start();
|
||||||
|
|
||||||
process.StandardInput.Close(); // nothing for you to read!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStop()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
EventLog.WriteEntry("Stopping "+descriptor.Id);
|
|
||||||
orderlyShutdown = true;
|
|
||||||
process.Kill();
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException)
|
|
||||||
{
|
|
||||||
// already terminated
|
|
||||||
}
|
|
||||||
process.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue