/// <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);
        }
示例#2
0
 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;
     }
 }
示例#3
0
        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;
            }
        }