mirror of https://github.com/winsw/winsw
Merge pull request #532 from NextTurn/args
Support <startarguments> and <stoparguments>pull/513/head
commit
3ca706678c
|
@ -92,9 +92,9 @@ Optionally set a different logging directory with `<logpath>` and startup `<logm
|
||||||
|
|
||||||
See the [Logging and error reporting](loggingAndErrorReporting.md) page for more info.
|
See the [Logging and error reporting](loggingAndErrorReporting.md) page for more info.
|
||||||
|
|
||||||
### argument
|
### Arguments
|
||||||
|
|
||||||
This element specifies the arguments to be passed to the executable.
|
`<argument>` element specifies the arguments to be passed to the executable.
|
||||||
Winsw will quote each argument if necessary, so do not put quotes in `<argument>` to avoid double quotation.
|
Winsw will quote each argument if necessary, so do not put quotes in `<argument>` to avoid double quotation.
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
|
@ -107,12 +107,12 @@ Winsw will quote each argument if necessary, so do not put quotes in `<argument>
|
||||||
|
|
||||||
### stopargument/stopexecutable
|
### stopargument/stopexecutable
|
||||||
|
|
||||||
When the service is requested to stop, winsw simply calls [TerminateProcess function](https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess) to kill the service instantly.
|
~~When the service is requested to stop, winsw simply calls [TerminateProcess function](https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess) to kill the service instantly.~~
|
||||||
However, if `<stopargument>` elements are present, winsw will instead launch another process of `<executable>` (or `<stopexecutable>` if that's specified) with the `<stopargument>` arguments, and expects that to initiate the graceful shutdown of the service process.
|
However, if `<stopargument>`/`<stoparguments>` elements are present, winsw will instead launch another process of `<executable>` (or `<stopexecutable>` if that's specified) with the specified arguments, and expects that to initiate the graceful shutdown of the service process.
|
||||||
|
|
||||||
Winsw will then wait for the two processes to exit on its own, before reporting back to Windows that the service has terminated.
|
Winsw will then wait for the two processes to exit on its own, before reporting back to Windows that the service has terminated.
|
||||||
|
|
||||||
When you use the `<stopargument>`, you must use `<startargument>` instead of `<argument>`. See the complete example below:
|
When you use the `<stopargument>`/`<stoparguments>`, you must use `<startargument>`/`<startarguments>` instead of `<argument>`. See the complete example below:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<executable>catalina.sh</executable>
|
<executable>catalina.sh</executable>
|
||||||
|
@ -123,9 +123,6 @@ When you use the `<stopargument>`, you must use `<startargument>` instead of `<a
|
||||||
<stopargument>stop</stopargument>
|
<stopargument>stop</stopargument>
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the name of the element is `startargument` and not `startarguments`.
|
|
||||||
As such, to specify multiple arguments, you'll specify multiple elements.
|
|
||||||
|
|
||||||
### stoptimeout
|
### stoptimeout
|
||||||
|
|
||||||
When the service is requested to stop, winsw first attempts to send a Ctrl+C signal,
|
When the service is requested to stop, winsw first attempts to send a Ctrl+C signal,
|
||||||
|
|
|
@ -157,7 +157,7 @@ SECTION: Executable management
|
||||||
This OPTION also enables termination of the executable via stop executable
|
This OPTION also enables termination of the executable via stop executable
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
<stoparguments>-stop true</stoparguments>-->
|
<stoparguments>-stop true</stoparguments>
|
||||||
-->
|
-->
|
||||||
<!--
|
<!--
|
||||||
SECTION: Service management
|
SECTION: Service management
|
||||||
|
|
|
@ -268,31 +268,31 @@ namespace winsw
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string? startarguments = _descriptor.Startarguments;
|
string? startArguments = _descriptor.StartArguments;
|
||||||
|
|
||||||
if (startarguments is null)
|
if (startArguments is null)
|
||||||
{
|
{
|
||||||
startarguments = _descriptor.Arguments;
|
startArguments = _descriptor.Arguments;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
startarguments += " " + _descriptor.Arguments;
|
startArguments += " " + _descriptor.Arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converting newlines, line returns, tabs into a single
|
// Converting newlines, line returns, tabs into a single
|
||||||
// space. This allows users to provide multi-line arguments
|
// space. This allows users to provide multi-line arguments
|
||||||
// in the xml for readability.
|
// in the xml for readability.
|
||||||
startarguments = Regex.Replace(startarguments, @"\s*[\n\r]+\s*", " ");
|
startArguments = Regex.Replace(startArguments, @"\s*[\n\r]+\s*", " ");
|
||||||
|
|
||||||
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
LogEvent("Starting " + _descriptor.Executable + ' ' + startArguments);
|
||||||
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);
|
Log.Info("Starting " + _descriptor.Executable + ' ' + startArguments);
|
||||||
|
|
||||||
// Load and start extensions
|
// Load and start extensions
|
||||||
ExtensionManager.LoadExtensions();
|
ExtensionManager.LoadExtensions();
|
||||||
ExtensionManager.FireOnWrapperStarted();
|
ExtensionManager.FireOnWrapperStarted();
|
||||||
|
|
||||||
LogHandler executableLogHandler = CreateExecutableLogHandler();
|
LogHandler executableLogHandler = CreateExecutableLogHandler();
|
||||||
StartProcess(_process, startarguments, _descriptor.Executable, executableLogHandler, true);
|
StartProcess(_process, startArguments, _descriptor.Executable, executableLogHandler, true);
|
||||||
ExtensionManager.FireOnProcessStarted(_process);
|
ExtensionManager.FireOnProcessStarted(_process);
|
||||||
|
|
||||||
_process.StandardInput.Close(); // nothing for you to read!
|
_process.StandardInput.Close(); // nothing for you to read!
|
||||||
|
@ -332,12 +332,12 @@ namespace winsw
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void StopIt()
|
private void StopIt()
|
||||||
{
|
{
|
||||||
string? stoparguments = _descriptor.Stoparguments;
|
string? stopArguments = _descriptor.StopArguments;
|
||||||
LogEvent("Stopping " + _descriptor.Id);
|
LogEvent("Stopping " + _descriptor.Id);
|
||||||
Log.Info("Stopping " + _descriptor.Id);
|
Log.Info("Stopping " + _descriptor.Id);
|
||||||
_orderlyShutdown = true;
|
_orderlyShutdown = true;
|
||||||
|
|
||||||
if (stoparguments is null)
|
if (stopArguments is null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -354,7 +354,7 @@ namespace winsw
|
||||||
{
|
{
|
||||||
SignalShutdownPending();
|
SignalShutdownPending();
|
||||||
|
|
||||||
stoparguments += " " + _descriptor.Arguments;
|
stopArguments += " " + _descriptor.Arguments;
|
||||||
|
|
||||||
Process stopProcess = new Process();
|
Process stopProcess = new Process();
|
||||||
string? executable = _descriptor.StopExecutable;
|
string? executable = _descriptor.StopExecutable;
|
||||||
|
@ -362,7 +362,7 @@ namespace winsw
|
||||||
executable ??= _descriptor.Executable;
|
executable ??= _descriptor.Executable;
|
||||||
|
|
||||||
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
|
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
|
||||||
StartProcess(stopProcess, stoparguments, executable, null, false);
|
StartProcess(stopProcess, stopArguments, executable, null, false);
|
||||||
|
|
||||||
Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id);
|
Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id);
|
||||||
WaitForProcessToExit(_process);
|
WaitForProcessToExit(_process);
|
||||||
|
|
|
@ -29,9 +29,9 @@ namespace winsw.Configuration
|
||||||
|
|
||||||
// Executable management
|
// Executable management
|
||||||
public string Arguments => string.Empty;
|
public string Arguments => string.Empty;
|
||||||
public string? Startarguments => null;
|
public string? StartArguments => null;
|
||||||
public string? StopExecutable => null;
|
public string? StopExecutable => null;
|
||||||
public string? Stoparguments => null;
|
public string? StopArguments => null;
|
||||||
public string WorkingDirectory => Path.GetDirectoryName(ExecutablePath)!;
|
public string WorkingDirectory => Path.GetDirectoryName(ExecutablePath)!;
|
||||||
public ProcessPriorityClass Priority => ProcessPriorityClass.Normal;
|
public ProcessPriorityClass Priority => ProcessPriorityClass.Normal;
|
||||||
public TimeSpan StopTimeout => TimeSpan.FromSeconds(15);
|
public TimeSpan StopTimeout => TimeSpan.FromSeconds(15);
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace winsw.Configuration
|
||||||
|
|
||||||
// Executable management
|
// Executable management
|
||||||
string Arguments { get; }
|
string Arguments { get; }
|
||||||
string? Startarguments { get; }
|
string? StartArguments { get; }
|
||||||
string? StopExecutable { get; }
|
string? StopExecutable { get; }
|
||||||
string? Stoparguments { get; }
|
string? StopArguments { get; }
|
||||||
string WorkingDirectory { get; }
|
string WorkingDirectory { get; }
|
||||||
ProcessPriorityClass Priority { get; }
|
ProcessPriorityClass Priority { get; }
|
||||||
TimeSpan StopTimeout { get; }
|
TimeSpan StopTimeout { get; }
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace winsw
|
||||||
public string? StopExecutable => SingleElement("stopexecutable", true);
|
public string? StopExecutable => SingleElement("stopexecutable", true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Arguments or multiple optional argument elements which overrule the arguments element.
|
/// <c>arguments</c> or multiple optional <c>argument</c> elements which overrule the arguments element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Arguments
|
public string Arguments
|
||||||
{
|
{
|
||||||
|
@ -193,33 +193,56 @@ namespace winsw
|
||||||
{
|
{
|
||||||
string? arguments = AppendTags("argument", null);
|
string? arguments = AppendTags("argument", null);
|
||||||
|
|
||||||
if (arguments is null)
|
if (!(arguments is null))
|
||||||
{
|
|
||||||
XmlNode? argumentsNode = dom.SelectSingleNode("//arguments");
|
|
||||||
|
|
||||||
if (argumentsNode is null)
|
|
||||||
{
|
|
||||||
return Defaults.Arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XmlNode? argumentsNode = dom.SelectSingleNode("//arguments");
|
||||||
|
|
||||||
|
return argumentsNode is null ? Defaults.Arguments : Environment.ExpandEnvironmentVariables(argumentsNode.InnerText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiple optional startargument elements.
|
/// <c>startarguments</c> or multiple optional <c>startargument</c> elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Startarguments => AppendTags("startargument", Defaults.Startarguments);
|
public string? StartArguments
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string? startArguments = AppendTags("startargument", null);
|
||||||
|
|
||||||
|
if (!(startArguments is null))
|
||||||
|
{
|
||||||
|
return startArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlNode? startArgumentsNode = dom.SelectSingleNode("//startarguments");
|
||||||
|
|
||||||
|
return startArgumentsNode is null ? null : Environment.ExpandEnvironmentVariables(startArgumentsNode.InnerText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Multiple optional stopargument elements.
|
/// <c>stoparguments</c> or multiple optional <c>stopargument</c> elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Stoparguments => AppendTags("stopargument", Defaults.Stoparguments);
|
public string? StopArguments
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string? stopArguments = AppendTags("stopargument", null);
|
||||||
|
|
||||||
|
if (!(stopArguments is null))
|
||||||
|
{
|
||||||
|
return stopArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlNode? stopArgumentsNode = dom.SelectSingleNode("//stoparguments");
|
||||||
|
|
||||||
|
return stopArgumentsNode is null ? null : Environment.ExpandEnvironmentVariables(stopArgumentsNode.InnerText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string WorkingDirectory
|
public string WorkingDirectory
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue