56 lines
1.8 KiB
C#
56 lines
1.8 KiB
C#
|
using System.Reactive.Linq;
|
||
|
using System.Reactive.Subjects;
|
||
|
using System.Reactive.Threading.Tasks;
|
||
|
using CliWrap;
|
||
|
|
||
|
namespace InnovEnergy.Lib.Utils.WIP;
|
||
|
|
||
|
using Data = IReadOnlyList<Byte>;
|
||
|
|
||
|
public class ObservableProcess
|
||
|
{
|
||
|
private readonly Command _Command;
|
||
|
private readonly CancellationTokenSource _Kill = new CancellationTokenSource();
|
||
|
private readonly CancellationTokenSource _Interrupt = new CancellationTokenSource();
|
||
|
|
||
|
private readonly ObserverPipeSource _StdIn = new ObserverPipeSource();
|
||
|
private readonly ReadablePipeTarget _StdOut = new ReadablePipeTarget();
|
||
|
private readonly ReadablePipeTarget _StdErr = new ReadablePipeTarget();
|
||
|
|
||
|
public IObserver<Data> StdIn => _StdIn;
|
||
|
|
||
|
private readonly Subject<Int32> _Pid = new Subject<Int32>();
|
||
|
private readonly Subject<Int32> _ExitCode = new Subject<Int32>();
|
||
|
|
||
|
public Task<Int32> Pid { get; }
|
||
|
public Task<Int32> ExitCode { get; }
|
||
|
|
||
|
|
||
|
public Task<Data> Read(Int32 nBytes) => _StdOut.Read(nBytes);
|
||
|
|
||
|
public ObservableProcess(Command command)
|
||
|
{
|
||
|
_Command = command;
|
||
|
Pid = _Pid.ToTask();
|
||
|
ExitCode = _ExitCode.ToTask();
|
||
|
}
|
||
|
|
||
|
public void Start()
|
||
|
{
|
||
|
var commandTask = _Command
|
||
|
.WithStandardInputPipe(_StdIn)
|
||
|
.WithStandardOutputPipe(_StdOut)
|
||
|
.WithStandardErrorPipe(_StdErr)
|
||
|
.ExecuteAsync(_Kill.Token, _Interrupt.Token);
|
||
|
|
||
|
_Pid.OnNext(commandTask.ProcessId);
|
||
|
|
||
|
commandTask.Task
|
||
|
.ToObservable()
|
||
|
.Select(t => t.ExitCode)
|
||
|
.Subscribe(_ExitCode);
|
||
|
}
|
||
|
|
||
|
public void Kill() => _Kill.Cancel();
|
||
|
public void Interrupt() => _Interrupt.Cancel();
|
||
|
}
|