|
|
@@ -0,0 +1,104 @@
|
|
|
+using System;
|
|
|
+using System.Diagnostics;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using Debug = UnityEngine.Debug;
|
|
|
+using Path = System.IO.Path;
|
|
|
+
|
|
|
+namespace ET
|
|
|
+{
|
|
|
+ public static class ProcessHelper
|
|
|
+ {
|
|
|
+ public static System.Diagnostics.Process Run(string exe, string arguments, string workingDirectory = ".", bool waitExit = false)
|
|
|
+ {
|
|
|
+ //Log.Debug($"Process Run exe:{exe} ,arguments:{arguments} ,workingDirectory:{workingDirectory}");
|
|
|
+ try
|
|
|
+ {
|
|
|
+ bool redirectStandardOutput = false;
|
|
|
+ bool redirectStandardError = false;
|
|
|
+ bool useShellExecute = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
|
|
+
|
|
|
+ if (waitExit)
|
|
|
+ {
|
|
|
+ redirectStandardOutput = true;
|
|
|
+ redirectStandardError = true;
|
|
|
+ useShellExecute = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ ProcessStartInfo info = new ProcessStartInfo
|
|
|
+ {
|
|
|
+ FileName = exe,
|
|
|
+ Arguments = arguments,
|
|
|
+ CreateNoWindow = true,
|
|
|
+ UseShellExecute = useShellExecute,
|
|
|
+ WorkingDirectory = workingDirectory,
|
|
|
+ RedirectStandardOutput = redirectStandardOutput,
|
|
|
+ RedirectStandardError = redirectStandardError,
|
|
|
+ };
|
|
|
+
|
|
|
+ System.Diagnostics.Process process = System.Diagnostics.Process.Start(info);
|
|
|
+
|
|
|
+ if (waitExit)
|
|
|
+ {
|
|
|
+ WaitExitAsync(process);
|
|
|
+ }
|
|
|
+
|
|
|
+ return process;
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ throw new Exception($"dir: {Path.GetFullPath(workingDirectory)}, command: {exe} {arguments}", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task WaitExitAsync(System.Diagnostics.Process process)
|
|
|
+ {
|
|
|
+ await process.WaitForExitAsync();
|
|
|
+#if UNITY
|
|
|
+ Debug.Log($"process exit, exitcode: {process.ExitCode} {process.StandardOutput.ReadToEnd()} {process.StandardError.ReadToEnd()}");
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+#if UNITY
|
|
|
+ private static async Task WaitForExitAsync(this System.Diagnostics.Process self)
|
|
|
+ {
|
|
|
+ if (!self.HasExited)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ self.EnableRaisingEvents = true;
|
|
|
+ }
|
|
|
+ catch (InvalidOperationException)
|
|
|
+ {
|
|
|
+ if (self.HasExited)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+
|
|
|
+ var tcs = new TaskCompletionSource<bool>();
|
|
|
+
|
|
|
+ void Handler(object s, EventArgs e) => tcs.TrySetResult(true);
|
|
|
+
|
|
|
+ self.Exited += Handler;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (self.HasExited)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await tcs.Task;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ self.Exited -= Handler;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ }
|
|
|
+}
|