Skip to content

Commit

Permalink
Merge pull request #224 from oleg-nenashev/bug/Issue218_fix2
Browse files Browse the repository at this point in the history
Issue #218 - ProcessHelper#StartProcessAndCallbackForExit() should redirect STDOUT/STDERR when LogHandler is defined
  • Loading branch information
oleg-nenashev committed Jun 11, 2017
2 parents cfacfe3 + 69857d5 commit a2c2a9d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
20 changes: 11 additions & 9 deletions src/Core/ServiceWrapper/Main.cs
Expand Up @@ -136,7 +136,8 @@ private void CopyFile(string sourceFileName, string destFileName)
/// <summary>
/// Handle the creation of the logfiles based on the optional logmode setting.
/// </summary>
private void HandleLogfiles()
/// <returns>Log Handler, which should be used for the spawned process</returns>
private LogHandler CreateExecutableLogHandler()
{
string logDirectory = _descriptor.LogDirectory;

Expand All @@ -147,7 +148,7 @@ private void HandleLogfiles()

LogHandler logAppender = _descriptor.LogHandler;
logAppender.EventLogger = this;
logAppender.log(_process.StandardOutput.BaseStream, _process.StandardError.BaseStream);
return logAppender;
}

public void LogEvent(String message)
Expand Down Expand Up @@ -247,12 +248,10 @@ protected override void OnStart(string[] _)
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);

StartProcess(_process, startarguments, _descriptor.Executable);
LogHandler executableLogHandler = CreateExecutableLogHandler();
StartProcess(_process, startarguments, _descriptor.Executable, executableLogHandler, true);
ExtensionManager.FireOnProcessStarted(_process);

// send stdout and stderr to its respective output file.
HandleLogfiles();

_process.StandardInput.Close(); // nothing for you to read!
}

Expand Down Expand Up @@ -322,7 +321,8 @@ private void StopIt()
executable = _descriptor.Executable;
}

StartProcess(stopProcess, stoparguments, executable);
// TODO: Redirect logging to Log4Net once https://github.com/kohsuke/winsw/pull/213 is integrated
StartProcess(stopProcess, stoparguments, executable, null, false);

Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id);
WaitForProcessToExit(_process);
Expand Down Expand Up @@ -407,7 +407,7 @@ private void SignalShutdownComplete()
Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus);
}

private void StartProcess(Process processToStart, string arguments, String executable)
private void StartProcess(Process processToStart, string arguments, String executable, LogHandler logHandler, bool redirectStdin)
{

// Define handler of the completed process
Expand Down Expand Up @@ -454,7 +454,9 @@ private void StartProcess(Process processToStart, string arguments, String execu
envVars: _envs,
workingDirectory: _descriptor.WorkingDirectory,
priority: _descriptor.Priority,
callback: processCompletionCallback);
callback: processCompletionCallback,
logHandler: logHandler,
redirectStdin: redirectStdin);
}

public static int Main(string[] args)
Expand Down
17 changes: 13 additions & 4 deletions src/Core/WinSWCore/Util/ProcessHelper.cs
Expand Up @@ -129,18 +129,20 @@ public static void StopProcessAndChildren(int pid, TimeSpan stopTimeout, bool st
/// <param name="workingDirectory">Working directory</param>
/// <param name="priority">Priority</param>
/// <param name="callback">Completion callback. If null, the completion won't be monitored</param>
/// <param name="logHandler">Log handler. If enabled, logs will be redirected to the process and then reported</param>
/// <param name="redirectStdin">Redirect standard input</param>
public static void StartProcessAndCallbackForExit(Process processToStart, String executable = null, string arguments = null, Dictionary<string, string> envVars = null,
string workingDirectory = null, ProcessPriorityClass? priority = null, ProcessCompletionCallback callback = null)
string workingDirectory = null, ProcessPriorityClass? priority = null, ProcessCompletionCallback callback = null, bool redirectStdin = true, LogHandler logHandler = null)
{
var ps = processToStart.StartInfo;
ps.FileName = executable ?? ps.FileName;
ps.Arguments = arguments ?? ps.Arguments;
ps.WorkingDirectory = workingDirectory ?? ps.WorkingDirectory;
ps.CreateNoWindow = false;
ps.UseShellExecute = false;
ps.RedirectStandardInput = false;
ps.RedirectStandardOutput = false;
ps.RedirectStandardError = false;
ps.RedirectStandardInput = redirectStdin;
ps.RedirectStandardOutput = logHandler != null;
ps.RedirectStandardError = logHandler != null;

if (envVars != null)
{
Expand All @@ -160,6 +162,13 @@ public static void StopProcessAndChildren(int pid, TimeSpan stopTimeout, bool st
processToStart.PriorityClass = priority.Value;
}

// Redirect logs if required
if (logHandler != null)
{
Logger.Debug("Forwarding logs of the process " + processToStart + " to " + logHandler);
logHandler.log(processToStart.StandardOutput.BaseStream, processToStart.StandardError.BaseStream);
}

// monitor the completion of the process
if (callback != null)
{
Expand Down

0 comments on commit a2c2a9d

Please sign in to comment.