Tyrrrz/CliWrap

Ignore waiting for output stream when main process is finished, but it has active children reusing the same output streams

dmilosz opened this issue · 1 comments

Details

When starting process which creates another process reusing the same window, CliWrap await ExecuteAsync() waits for entire processes tree to be finished, even when the main parent process is already finished.

Example reproduction:

Console.WriteLine($"Program started at: {DateTime.Now.ToLongTimeString()}");

var cmd = Cli.Wrap("powershell")
    .WithArguments("Start-Process -NoNewWindow -FilePath \"powershell\" -ArgumentList \"'sleep 5'\"; exit 0")
    .WithStandardOutputPipe(PipeTarget.ToDelegate(line => Console.WriteLine($"STDOUT {line}")))
    .WithStandardErrorPipe(PipeTarget.ToDelegate(line => Console.WriteLine($"STDERR {line}")));

var result = await cmd.ExecuteAsync();

Console.WriteLine($"Process started at: {result.StartTime.DateTime.ToLongTimeString()}");
Console.WriteLine($"Process finished with exit code: {result.ExitCode}");
Console.WriteLine($"Process finished at: {result.ExitTime.DateTime.ToLongTimeString()}");

Console.WriteLine($"Program finished at: {DateTime.Now.ToLongTimeString()}");

Output is:

Program started at: 12:23:49 PM
Process started at: 12:23:49 PM
Process finished with exit code: 0
Process finished at: 12:23:50 PM
Program finished at: 12:23:55 PM

But I'd like output to be:

Program started at: 12:23:49 PM
Process started at: 12:23:49 PM
Process finished with exit code: 0
Process finished at: 12:23:50 PM
Program finished at: 12:23:50 PM

So that it doesn't wait for dependent process to be finished, even if it uses the same output.

Currently there is no way to achieve this with CliWrap. Possible solution:

Add extra feature in CliWrap, so that it's possible to define that we don't want to wait for the output after process is finished:

var cmd = Cli.Wrap("powershell")
    .WithArguments("Start-Process -NoNewWindow -FilePath \"powershell\" -ArgumentList \"'sleep 5'\"; exit 0")
    .WithWaitingForOutputProcessing(false)
    .WithStandardOutputPipe(PipeTarget.ToDelegate(line => Console.WriteLine($"STDOUT {line}")))
    .WithStandardErrorPipe(PipeTarget.ToDelegate(line => Console.WriteLine($"STDERR {line}")));

I have already implemented solution in my fork and I can make a PR.

Checklist

  • I have looked through existing issues to make sure that this feature has not been requested before
  • I have provided a descriptive title for this issue
  • I am aware that even valid feature requests may be rejected if they do not align with the project's goals
  • I have sponsored this project

Related: #185