public ToolExecutionResult(ToolExecutionOptions options, Process process) { this.Process = process; this.ProcessId = process.Id; this.ExitCode = int.MinValue; if (options.StartInfo.RedirectStandardOutput) { this.standartStreamOpenStatus |= StandartOutputOpened; this.standartOutputBuffer = new StringBuilder(); process.OutputDataReceived += this.OnOutputDataReceived; process.BeginOutputReadLine(); } if (options.StartInfo.RedirectStandardError) { this.standartErrorBuffer = new StringBuilder(); this.standartStreamOpenStatus |= StandartErrorOpened; process.ErrorDataReceived += this.OnErrorDataReceived; process.BeginErrorReadLine(); } }
private static IEnumerable RunAsync(ToolExecutionOptions options) { yield return null; var isDotNetInstalled = false; if (IsWindows) { isDotNetInstalled = Get45or451FromRegistry() != null; } if (options.RequireDotNetRuntime && isDotNetInstalled == false) { if (string.IsNullOrEmpty(MonoPath)) throw new InvalidOperationException("No .NET runtime found on machine."); options.StartInfo.Arguments = ToolExecutionOptions.ConcatArguments(options.StartInfo.FileName) + " " + options.StartInfo.Arguments; options.StartInfo.FileName = MonoPath; } if (options.CaptureStandartError) options.StartInfo.RedirectStandardError = true; if (options.CaptureStandartOutput) options.StartInfo.RedirectStandardOutput = true; if (Settings.Current.Verbose) UnityEngine.Debug.Log(string.Format("Starting process '{0}' at '{1}' with arguments '{2}' and environment variables '{3}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments, ConcatDictionaryValues(options.StartInfo.EnvironmentVariables))); var processStarted = DateTime.UtcNow; var timeout = options.ExecutionTimeout; if (timeout <= TimeSpan.Zero) timeout = TimeSpan.MaxValue; var process = Process.Start(options.StartInfo); if (process == null) throw new InvalidOperationException("Unknown process start error."); var result = new ToolExecutionResult(options, process); if (options.WaitForExit == false) { //if (Settings.Current.Verbose) // UnityEngine.Debug.Log(string.Format("Yielding started process '{0}' at '{1}' with arguments '{2}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments)); yield return result; yield break; } var hasExited = false; while (hasExited == false) { if (DateTime.UtcNow - processStarted > timeout) throw new TimeoutException(); try { process.Refresh(); hasExited = process.HasExited; } catch (InvalidOperationException) { // ignored } catch (System.ComponentModel.Win32Exception) { // ignored } yield return Promise.Delayed(TimeSpan.FromMilliseconds(50)); } processStarted = DateTime.UtcNow; timeout = options.TerminationTimeout; if (timeout <= TimeSpan.Zero) timeout = TimeSpan.MaxValue; while (result.HasPendingData) { if (DateTime.UtcNow - processStarted > timeout) throw new TimeoutException(); yield return Promise.Delayed(TimeSpan.FromMilliseconds(50)); } result.ExitCode = process.ExitCode; if (Settings.Current.Verbose) UnityEngine.Debug.Log(string.Format("Process #{1} '{0}' has exited with code {2}.", options.StartInfo.FileName, result.ProcessId, result.ExitCode)); yield return result; }
public static Promise<ToolExecutionResult> Run(ToolExecutionOptions options) { if (options == null) throw new ArgumentNullException("options"); return new Coroutine<ToolExecutionResult>(RunAsync(options)); }