1+ using System . Diagnostics ;
2+ using System . Threading ;
3+ using System . Threading . Tasks ;
4+ using R3 ;
5+
6+ namespace DevEnv ;
7+
8+ public sealed class Process ( string command , params string [ ] args )
9+ {
10+ private readonly ReplaySubject < string > stdOut = new ( ) ;
11+
12+ private readonly ReplaySubject < string > stdErr = new ( ) ;
13+
14+ private readonly string command = command ;
15+
16+ private readonly string [ ] args = args ;
17+
18+ public Observable < string > StdOut => stdOut ;
19+
20+ public Observable < string > StdErr => stdErr ;
21+
22+ public async Task < int > ExecuteAsync ( CancellationToken cancellationToken )
23+ {
24+ ProcessStartInfo processStartInfo = new ( )
25+ {
26+ FileName = command ,
27+ Arguments = string . Join ( ' ' , args ) ,
28+ RedirectStandardOutput = true ,
29+ RedirectStandardError = true ,
30+ UseShellExecute = false ,
31+ CreateNoWindow = true ,
32+ } ;
33+
34+ using System . Diagnostics . Process process = new ( )
35+ {
36+ StartInfo = processStartInfo ,
37+ } ;
38+
39+ process . OutputDataReceived += ( sender , e ) =>
40+ {
41+ if ( e . Data != null )
42+ {
43+ stdOut . OnNext ( e . Data ) ;
44+ }
45+ } ;
46+
47+ process . ErrorDataReceived += ( sender , e ) =>
48+ {
49+ if ( e . Data != null )
50+ {
51+ stdErr . OnNext ( e . Data ) ;
52+ }
53+ } ;
54+
55+ process . Start ( ) ;
56+
57+ process . BeginOutputReadLine ( ) ;
58+ process . BeginErrorReadLine ( ) ;
59+
60+ await process . WaitForExitAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
61+
62+ return process . ExitCode ;
63+ }
64+ }
0 commit comments