@@ -80,40 +80,83 @@ public static Task sleep(TimeSpan timeSpan, CancellationToken cancellationToken
8080 return Task . Delay ( timeSpan , cancellationToken ) ;
8181 }
8282
83- public static async Task < string > withTimeout ( string command , int seconds )
83+ public static async Task < string > withTimeout ( FormattableString command , int seconds )
8484 {
8585 using ( var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( seconds ) ) )
8686 {
87- return await ProcessStartAsync ( command , cts . Token ) ;
87+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cts . Token ) ) . StdOut ;
8888 }
8989 }
9090
91- public static async Task < string > withTimeout ( string command , TimeSpan timeSpan )
91+ public static async Task < ( string StdOut , string StdError ) > withTimeout2 ( FormattableString command , int seconds )
92+ {
93+ using ( var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( seconds ) ) )
94+ {
95+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cts . Token ) ) ;
96+ }
97+ }
98+
99+ public static async Task < string > withTimeout ( FormattableString command , TimeSpan timeSpan )
92100 {
93101 using ( var cts = new CancellationTokenSource ( timeSpan ) )
94102 {
95- return await ProcessStartAsync ( command , cts . Token ) ;
103+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cts . Token ) ) . StdOut ;
96104 }
97105 }
98106
99- public static async Task < string > withCancellation ( string command , CancellationToken cancellationToken )
107+ public static async Task < ( string StdOut , string StdError ) > withTimeout2 ( FormattableString command , TimeSpan timeSpan )
100108 {
101- return await ProcessStartAsync ( command , cancellationToken ) ;
109+ using ( var cts = new CancellationTokenSource ( timeSpan ) )
110+ {
111+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cts . Token ) ) ;
112+ }
113+ }
114+
115+ public static async Task < string > withCancellation ( FormattableString command , CancellationToken cancellationToken )
116+ {
117+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cancellationToken ) ) . StdOut ;
118+ }
119+
120+ public static async Task < ( string StdOut , string StdError ) > withCancellation2 ( FormattableString command , CancellationToken cancellationToken )
121+ {
122+ return ( await ProcessStartAsync ( EscapeFormattableString . Escape ( command ) , cancellationToken ) ) ;
102123 }
103124
104125 public static Task < string > run ( FormattableString command , CancellationToken cancellationToken = default )
105126 {
106127 return process ( EscapeFormattableString . Escape ( command ) , cancellationToken ) ;
107128 }
108129
130+ public static Task < ( string StdOut , string StdError ) > run2 ( FormattableString command , CancellationToken cancellationToken = default )
131+ {
132+ return process2 ( EscapeFormattableString . Escape ( command ) , cancellationToken ) ;
133+ }
134+
109135 public static string escape ( FormattableString command )
110136 {
111137 return EscapeFormattableString . Escape ( command ) ;
112138 }
113139
114- public static Task < string > process ( string command , CancellationToken cancellationToken = default )
140+ public static async Task < string > process ( string command , CancellationToken cancellationToken = default )
141+ {
142+ return ( await ProcessStartAsync ( command , cancellationToken ) ) . StdOut ;
143+ }
144+
145+ public static async Task < ( string StdOut , string StdError ) > process2 ( string command , CancellationToken cancellationToken = default )
115146 {
116- return ProcessStartAsync ( command , cancellationToken ) ;
147+ return await ProcessStartAsync ( command , cancellationToken ) ;
148+ }
149+
150+ public static async Task < T > ignore < T > ( Task < T > task )
151+ {
152+ try
153+ {
154+ return await task . ConfigureAwait ( false ) ;
155+ }
156+ catch ( ProcessErrorException )
157+ {
158+ return default ( T ) ! ;
159+ }
117160 }
118161
119162 public static async Task < string > question ( string question )
@@ -145,20 +188,43 @@ public static IDisposable color(ConsoleColor color)
145188 return new ColorScope ( current ) ;
146189 }
147190
148- static async Task < string > ProcessStartAsync ( string command , CancellationToken cancellationToken , bool forceSilcent = false )
191+ static async Task < ( string StdOut , string StdError ) > ProcessStartAsync ( string command , CancellationToken cancellationToken , bool forceSilcent = false )
149192 {
150193 var cmd = shell + " " + command ;
151- var sb = new StringBuilder ( ) ;
152- await foreach ( var item in ProcessX . StartAsync ( cmd , workingDirectory , envVars ) . WithCancellation ( cancellationToken ) . ConfigureAwait ( false ) )
194+ var sbOut = new StringBuilder ( ) ;
195+ var sbError = new StringBuilder ( ) ;
196+
197+ var ( _, stdout , stderror ) = ProcessX . GetDualAsyncEnumerable ( cmd , workingDirectory , envVars ) ;
198+
199+ var runStdout = Task . Run ( async ( ) =>
153200 {
154- sb . AppendLine ( item ) ;
201+ await foreach ( var item in stdout . WithCancellation ( cancellationToken ) . ConfigureAwait ( false ) )
202+ {
203+ sbOut . AppendLine ( item ) ;
155204
156- if ( verbose && ! forceSilcent )
205+ if ( verbose && ! forceSilcent )
206+ {
207+ Console . WriteLine ( item ) ;
208+ }
209+ }
210+ } ) ;
211+
212+ var runStdError = Task . Run ( async ( ) =>
213+ {
214+ await foreach ( var item in stderror . WithCancellation ( cancellationToken ) . ConfigureAwait ( false ) )
157215 {
158- Console . WriteLine ( item ) ;
216+ sbError . AppendLine ( item ) ;
217+
218+ if ( verbose && ! forceSilcent )
219+ {
220+ Console . WriteLine ( item ) ;
221+ }
159222 }
160- }
161- return sb . ToString ( ) ;
223+ } ) ;
224+
225+ await Task . WhenAll ( runStdout , runStdError ) . ConfigureAwait ( false ) ;
226+
227+ return ( sbOut . ToString ( ) , sbError . ToString ( ) ) ;
162228 }
163229
164230 class ColorScope : IDisposable
0 commit comments