ProcessHelper.cs 3.1 KB

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