@@ -100,78 +100,86 @@ private Process StartGitProcess(params string[] args)
100100 StandardOutputEncoding = System . Text . Encoding . UTF8 ,
101101 StandardErrorEncoding = System . Text . Encoding . UTF8 ,
102102 } ;
103+ #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
103104 foreach ( var a in args )
104105 procInfo . ArgumentList . Add ( a ) ;
105-
106-
106+ #else
107+ procInfo . Arguments = WindowsEscapeArguments ( args ) ;
108+ #endif
107109 return Process . Start ( procInfo ) ;
108110 }
109111
110- private void HandleProcessExit ( Process proc , Task outputReaderTask , params string [ ] args )
112+
113+ #if ! ( NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER )
114+ private static string WindowsEscapeArguments ( params string [ ] args )
111115 {
112- // Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
113- var timeout = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? 15_000 : 3_000 ;
114- if ( ! proc . WaitForExit ( timeout ) )
115- {
116- proc . Kill ( ) ;
117- throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command timed out") ;
118- }
116+ // based on the logic from http://stackoverflow.com/questions/5510343/escape-command-line-arguments-in-c-sharp.
119117
120- if ( proc . ExitCode != 0 )
121- throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command failed: " + proc . StandardError . ReadToEnd ( ) ) ;
118+ if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
119+ throw new InvalidOperationException ( "The nestandard2.0 build is only supported on Windows old .NET Framework" ) ;
122120
123- outputReaderTask . Wait ( ) ;
121+ return string . Join ( " " , args . Select ( a => {
122+ a = Regex . Replace ( a , @"(\\*)" + "\" " , @"$1$1\" + "\" " ) ;
123+ return "\" " + Regex . Replace ( a , @"(\\+)$" , @"$1$1" ) + "\" " ;
124+ } ) ) ;
124125 }
126+ #endif
125127
126- private string [ ] RunGitCommand ( params string [ ] args )
127- {
128- var proc = StartGitProcess ( args ) ;
129128
130- var outputLines = new List < string > ( ) ;
131- var outputReaderTask = Task . Run ( ( ) =>
129+ private void HandleProcessExit ( Process proc , Task outputReaderTask , params string [ ] args )
130+ {
131+ try
132132 {
133- string line ;
134- while ( ( line = proc . StandardOutput . ReadLine ( ) ) != null )
133+ // Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
134+ var timeout = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? 15_000 : 3_000 ;
135+ if ( ! proc . WaitForExit ( timeout ) )
135136 {
136- if ( line . Length > 0 )
137- outputLines . Add ( line ) ;
137+ proc . Kill ( ) ;
138+ throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command timed out" ) ;
138139 }
139- } ) ;
140140
141- HandleProcessExit ( proc , outputReaderTask , args ) ;
141+ if ( proc . ExitCode != 0 )
142+ throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command failed: " + proc . StandardError . ReadToEnd ( ) ) ;
142143
143- return outputLines . ToArray ( ) ;
144+ outputReaderTask . Wait ( ) ;
145+ }
146+ finally
147+ {
148+ proc . Dispose ( ) ;
149+ }
144150 }
145151
146- private byte [ ] RunGitBinaryCommand ( params string [ ] args )
152+ private string [ ] RunGitCommand ( params string [ ] args )
147153 {
148- const int BUFFER_SIZE = 1024 ;
154+ var output = RunGitBinaryCommand ( args ) ;
149155
156+ using var reader = new StreamReader ( output ) ;
157+ return ReadAllLines ( reader ) ;
158+ }
159+
160+ private MemoryStream RunGitBinaryCommand ( params string [ ] args )
161+ {
150162 var proc = StartGitProcess ( args ) ;
151163
152- List < byte > ret = new ( ) ;
164+ MemoryStream ret = new ( ) ;
153165
154166 var outputReaderTask = Task . Run ( ( ) =>
155167 {
156- byte [ ] buffer = new byte [ BUFFER_SIZE ] ;
157-
158- int charsRead = 0 ;
159- while ( ( charsRead = proc . StandardOutput . BaseStream . Read ( buffer , 0 , BUFFER_SIZE ) ) != 0 )
160- {
161- ret . AddRange ( buffer . AsSpan ( 0 , charsRead ) . ToArray ( ) ) ;
162- }
168+ proc . StandardOutput . BaseStream . CopyTo ( ret ) ;
163169 } ) ;
164170
165171 HandleProcessExit ( proc , outputReaderTask , args ) ;
166172
167- return ret . ToArray ( ) ;
173+ ret . Position = 0 ;
174+ return ret ;
168175 }
169176
170177 static string [ ] ReadAllLines ( StreamReader reader )
171178 {
172179 var lines = new List < string > ( ) ;
173180 while ( ! reader . EndOfStream && reader . ReadLine ( ) is { } line )
174- lines . Add ( line ) ;
181+ if ( line . Length > 0 )
182+ lines . Add ( line ) ;
175183 return lines . ToArray ( ) ;
176184 }
177185
@@ -209,7 +217,7 @@ private byte[] GetOldBinaryContent(string file)
209217
210218 var data = RunGitBinaryCommand ( "cat-file" , "blob" , hash ) ;
211219
212- return data ;
220+ return data . ToArray ( ) ;
213221 }
214222 else
215223 {
@@ -323,7 +331,7 @@ internal void CheckOutputBinaryCore(byte[] outputBytes, string checkName, string
323331 {
324332 using ( var t = File . Create ( filename ) )
325333 {
326- t . Write ( outputBytes ) ;
334+ t . Write ( outputBytes , 0 , outputBytes . Length ) ;
327335 }
328336 }
329337 return ;
@@ -333,7 +341,7 @@ internal void CheckOutputBinaryCore(byte[] outputBytes, string checkName, string
333341 {
334342 using ( var t = File . Create ( filename ) )
335343 {
336- t . Write ( outputBytes ) ;
344+ t . Write ( outputBytes , 0 , outputBytes . Length ) ;
337345 }
338346
339347 if ( IsModified ( filename ) )
0 commit comments