/// <summary> /// Runs the given command in the OS shell (cmd on Windows, bash on Mac/Linux). /// </summary> public static bool RunInShell(string command, ShellProcessArgs processArgs, bool outputOnErrorOnly = true) { var output = UTinyShell.RunInShell(command, processArgs); if (!output.Succeeded) { Debug.LogError($"{UTinyConstants.ApplicationName}: {output.FullOutput}"); } else if (!outputOnErrorOnly) { Debug.Log($"{UTinyConstants.ApplicationName}: {output.FullOutput}"); } return(output.Succeeded); }
public static Process RunNoWait(string executable, string arguments, ShellProcessArgs processArgs, DataReceivedEventHandler outputReceived = null, DataReceivedEventHandler errorReceived = null) { try { var exeDir = Where(executable, processArgs.ExtraPaths); if (exeDir == null) { if (processArgs.ThrowOnError) { throw new FileNotFoundException($"Could not find command '{executable}' in the given search locations."); } return(null); } return(StartProcess(Path.Combine(exeDir.FullName, executable), arguments, processArgs.WorkingDirectory, outputReceived, errorReceived)); } catch (Exception e) { TinyEditorAnalytics.SendException("Shell.RunNoWait", e); throw; } }
public static ShellProcessOutput RunInShell(string command, ShellProcessArgs args) { Assert.IsFalse(string.IsNullOrEmpty(command)); Assert.IsNotNull(args); try { var extraPaths = args.ExtraPaths; var workingDirectory = args.WorkingDirectory; var throwOnError = args.ThrowOnError; var runOutput = new ShellProcessOutput(); var hasErrors = false; var output = new StringBuilder(); var logOutput = new StringBuilder(); var errorOutput = new StringBuilder(); // Setup shell command if (extraPaths != null) { var sb = new StringBuilder(128); foreach (var part in extraPaths) { if (string.IsNullOrEmpty(part)) { continue; } if (sb.Length > 0) { sb.Append(s_PathSeparator); } #if UNITY_EDITOR_WIN sb.Append(part.Trim('"')); #else sb.Append(part[0] == '"' ? part : part.DoubleQuoted()); #endif } #if UNITY_EDITOR_WIN command = $"SET PATH={sb}{s_PathSeparator}%PATH%{Environment.NewLine}{command}"; #else command = $"export PATH={sb}{s_PathSeparator}$PATH{Environment.NewLine}{command}"; #endif } LogProcessData($"TINY SHELL> {(workingDirectory?.FullName ?? new DirectoryInfo(".").FullName)}", logOutput); LogProcessData(command, logOutput); // Setup temporary command file var tmpCommandFile = Path.GetTempPath() + Guid.NewGuid().ToString(); #if UNITY_EDITOR_WIN tmpCommandFile += ".bat"; #else tmpCommandFile += ".sh"; #endif File.WriteAllText(tmpCommandFile, command); // Prepare data received handlers DataReceivedEventHandler outputReceived = (sender, e) => { LogProcessData(e.Data, output); logOutput.Append(e.Data); }; DataReceivedEventHandler errorReceived = (sender, e) => { LogProcessData(e.Data, output); errorOutput.Append(e.Data); logOutput.Append(e.Data); if (!string.IsNullOrEmpty(e.Data)) { hasErrors = true; } }; // Run command in shell and wait for exit try { #if UNITY_EDITOR_WIN using (var process = StartProcess("cmd.exe", $"/Q /C \"{tmpCommandFile}\"", workingDirectory, outputReceived, errorReceived)) #else using (var process = StartProcess("bash", $"\"{tmpCommandFile}\"", workingDirectory, outputReceived, errorReceived)) #endif { var exitCode = WaitForProcess(process, output, args.MaxIdleTimeInMilliseconds); runOutput.ExitCode = exitCode; runOutput.Command = command; runOutput.CommandOutput = output.ToString(); runOutput.FullOutput = logOutput.ToString(); runOutput.ErrorOutput = errorOutput.ToString(); LogProcessData($"Process exited with code '{exitCode}'", logOutput); hasErrors |= (exitCode != 0); } } finally { File.Delete(tmpCommandFile); } if (hasErrors && throwOnError) { throw new Exception($"{UTinyConstants.ApplicationName}: " + errorOutput.ToString()); } runOutput.Succeeded = !hasErrors; return(runOutput); } catch (Exception e) { TinyEditorAnalytics.SendException("Shell.RunInShell", e); throw; } }