ProcessHelper.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using System.Threading.Tasks;
  5. using Path = System.IO.Path;
  6. namespace ET
  7. {
  8. public static class ProcessHelper
  9. {
  10. public static Process Run(string exe, string arguments, string workingDirectory = ".", bool waitExit = false)
  11. {
  12. //Log.Debug($"Process Run exe:{exe} ,arguments:{arguments} ,workingDirectory:{workingDirectory}");
  13. try
  14. {
  15. bool redirectStandardOutput = true;
  16. bool redirectStandardError = true;
  17. bool useShellExecute = false;
  18. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  19. {
  20. redirectStandardOutput = false;
  21. redirectStandardError = false;
  22. useShellExecute = true;
  23. }
  24. if (waitExit)
  25. {
  26. redirectStandardOutput = true;
  27. redirectStandardError = true;
  28. useShellExecute = false;
  29. }
  30. ProcessStartInfo info = new ProcessStartInfo
  31. {
  32. FileName = exe,
  33. Arguments = arguments,
  34. CreateNoWindow = true,
  35. UseShellExecute = useShellExecute,
  36. WorkingDirectory = workingDirectory,
  37. RedirectStandardOutput = redirectStandardOutput,
  38. RedirectStandardError = redirectStandardError,
  39. };
  40. Process process = Process.Start(info);
  41. if (waitExit)
  42. {
  43. WaitExitAsync(process).Coroutine();
  44. }
  45. return process;
  46. }
  47. catch (Exception e)
  48. {
  49. throw new Exception($"dir: {Path.GetFullPath(workingDirectory)}, command: {exe} {arguments}", e);
  50. }
  51. }
  52. private static async ETTask WaitExitAsync(Process process)
  53. {
  54. await process.WaitForExitAsync();
  55. #if UNITY
  56. Log.Info($"process exit, exitcode: {process.ExitCode} {process.StandardOutput.ReadToEnd()} {process.StandardError.ReadToEnd()}");
  57. #endif
  58. }
  59. #if UNITY
  60. private static async Task WaitForExitAsync(this Process self)
  61. {
  62. if (!self.HasExited)
  63. {
  64. return;
  65. }
  66. try
  67. {
  68. self.EnableRaisingEvents = true;
  69. }
  70. catch (InvalidOperationException)
  71. {
  72. if (self.HasExited)
  73. {
  74. return;
  75. }
  76. throw;
  77. }
  78. var tcs = new TaskCompletionSource<bool>();
  79. void Handler(object s, EventArgs e) => tcs.TrySetResult(true);
  80. self.Exited += Handler;
  81. try
  82. {
  83. if (self.HasExited)
  84. {
  85. return;
  86. }
  87. await tcs.Task;
  88. }
  89. finally
  90. {
  91. self.Exited -= Handler;
  92. }
  93. }
  94. #endif
  95. }
  96. }