9
9
using System . Threading ;
10
10
using System . Collections . Concurrent ;
11
11
using System . Runtime . InteropServices ;
12
+ using System . Buffers ;
13
+ using System . Linq ;
12
14
13
15
namespace com . bbbirder . unityeditor
14
16
{
@@ -55,6 +57,7 @@ public struct ShellSettings
55
57
56
58
public static class Shell
57
59
{
60
+ readonly static Encoding DEFAULT_WINDOWS_CONSOLE_ENCODING = Encoding . GetEncoding ( "gbk" ) ;
58
61
public static Dictionary < string , string > DefaultEnvironment = new ( ) ;
59
62
internal static ConcurrentQueue < ( ShellRequest req , LogEventType type , object arg ) > queue = new ( ) ;
60
63
public static Dictionary < ShellRequest , StringBuilder > lineBuilders = new ( ) ;
@@ -135,14 +138,14 @@ static Process CreateProcess(string cmd, string workDirectory = ".", Dictionary<
135
138
start . RedirectStandardError =
136
139
start . RedirectStandardInput = true ;
137
140
138
- // start.StandardInputEncoding =
139
- // start.StandardOutputEncoding =
140
- // start.StandardErrorEncoding =
141
- // #if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
142
- // Encoding.Unicode;
143
- // #else
144
- // Encoding.UTF8;
145
- // #endif
141
+ start . StandardInputEncoding =
142
+ start . StandardOutputEncoding =
143
+ start . StandardErrorEncoding =
144
+ #if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
145
+ Encoding . Unicode ;
146
+ #else
147
+ Encoding . UTF8 ;
148
+ #endif
146
149
147
150
start. ArgumentList . Clear ( ) ;
148
151
foreach ( var arg in args )
@@ -179,7 +182,7 @@ public static ShellRequest RunCommand(string cmd, ShellSettings? settings = defa
179
182
"@echo off>nul\n " +
180
183
#endif
181
184
#if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
182
- "@chcp 65001>nul\n "
185
+ "@chcp 65001>nul\n " +
183
186
#endif
184
187
cmd ;
185
188
@@ -222,6 +225,56 @@ public static ShellRequest RunCommandLine(string executable, params object[] arg
222
225
return RunCommandLine ( executable , ShellSettings . Default , args ) ;
223
226
}
224
227
228
+ static IEnumerable < string > GetConsoleOutput ( StreamReader console )
229
+ {
230
+ const int BUFFER_SIZE = 40960 ;
231
+ var buffer = ArrayPool < byte > . Shared . Rent ( BUFFER_SIZE ) ;
232
+ while ( ! console . EndOfStream )
233
+ {
234
+ var index = 0 ;
235
+ var wchar = console . CurrentEncoding == Encoding . Unicode ;
236
+ while ( console . Peek ( ) != - 1 )
237
+ {
238
+ var b = console . Read ( ) ;
239
+ if ( wchar )
240
+ {
241
+ if ( index + 2 < buffer . Length )
242
+ {
243
+ if ( BitConverter . IsLittleEndian )
244
+ {
245
+ buffer [ index ++ ] = ( byte ) ( b & 0xff ) ;
246
+ buffer[ index ++ ] = ( byte ) ( b >> 8 ) ;
247
+ }
248
+ else
249
+ {
250
+ buffer [ index ++ ] = ( byte ) ( b >> 8 ) ;
251
+ buffer[ index ++ ] = ( byte ) ( b & 0xff ) ;
252
+ }
253
+ }
254
+ }
255
+ else
256
+ {
257
+ if ( index + 1 < buffer . Length )
258
+ {
259
+ buffer[ index ++ ] = ( byte ) b ;
260
+ }
261
+ }
262
+ }
263
+
264
+ var encoding = Encoding. UTF8;
265
+ #if UNITY_EDITOR_WIN && DETECT_STDOUT_ENCODING
266
+ UnityEngine . Debug . Log ( string . Join ( ',' , buffer . Select ( b => b . ToString ( "x2" ) ) . ToArray ( ) , 0 , index ) ) ;
267
+ UnityEngine. Debug . Log ( ConsoleUtils . IsValidUTF8 ( buffer , 0 , index ) + " " + index ) ;
268
+ if ( ! ConsoleUtils . IsValidUTF8 ( buffer , 0 , index ) )
269
+ {
270
+ encoding = DEFAULT_WINDOWS_CONSOLE_ENCODING;
271
+ }
272
+ #endif
273
+ var output = encoding. GetString ( buffer , 0 , index ) ;
274
+ yield return output;
275
+ }
276
+ ArrayPool< byte > . Shared . Return ( buffer ) ;
277
+ }
225
278
226
279
static ShellRequest QueueUpProcess ( Process p , string cmd , ShellSettings settings )
227
280
{
@@ -232,32 +285,18 @@ static ShellRequest QueueUpProcess(Process p, string cmd, ShellSettings settings
232
285
{
233
286
try
234
287
{
235
- var builder = new StringBuilder ( ) ;
236
-
237
- while ( ! p . StandardOutput . EndOfStream )
288
+ foreach ( var output in GetConsoleOutput ( p . StandardOutput ) )
238
289
{
239
- while ( p . StandardOutput . Peek ( ) > - 1 )
240
- {
241
- builder . Append ( ( char ) p . StandardOutput . Read ( ) ) ;
242
- }
243
- var output = builder . ToString ( ) ;
244
- builder . Clear ( ) ;
245
290
queue . Enqueue ( ( req , LogEventType . InfoLog , output ) ) ;
246
291
}
247
292
248
- while ( ! p . StandardError . EndOfStream )
293
+ foreach ( var output in GetConsoleOutput ( p . StandardError ) )
249
294
{
250
- string error = p . StandardError . ReadLine ( ) ;
251
-
252
- if ( ! string . IsNullOrEmpty ( error ) )
253
- {
254
- if ( ! string . IsNullOrEmpty ( error ) )
255
- queue . Enqueue ( ( req , LogEventType . ErrorLog , error ) ) ;
256
- }
295
+ if ( ! string . IsNullOrEmpty ( output ) )
296
+ queue . Enqueue ( ( req , LogEventType . ErrorLog , output ) ) ;
257
297
}
258
298
259
299
queue . Enqueue ( ( req , LogEventType . EndStream , p . ExitCode ) ) ;
260
-
261
300
}
262
301
catch ( Exception e )
263
302
{
0 commit comments