Esempio n. 1
0
        /// <summary>
        /// Runs external program.
        /// </summary>
        /// <param name="App">Program filename.</param>
        /// <param name="CommandLine">Commandline</param>
        /// <param name="Input">Optional Input for the program (will be provided as stdin)</param>
        /// <param name="Options">Defines the options how to run. See ERunOptions.</param>
        /// <param name="Env">Environment to pass to program.</param>
        /// <returns>Object containing the exit code of the program as well as it's stdout output.</returns>
        public static ProcessResult Run(string App, string CommandLine = null, string Input = null, ERunOptions Options = ERunOptions.Default, Dictionary <string, string> Env = null)
        {
            App = ConvertSeparators(PathSeparator.Default, App);
            HostPlatform.Current.SetupOptionsForRun(ref App, ref Options, ref CommandLine);
            if (App == "ectool" || App == "zip" || App == "xcodebuild")
            {
                Options &= ~ERunOptions.AppMustExist;
            }

            if (Options.HasFlag(ERunOptions.AppMustExist) && !FileExists(Options.HasFlag(ERunOptions.NoLoggingOfRunCommand) ? true : false, App))
            {
                throw new AutomationException("BUILD FAILED: Couldn't find the executable to Run: {0}", App);
            }
            var StartTime = DateTime.UtcNow;

            TraceEventType SpewVerbosity = Options.HasFlag(ERunOptions.SpewIsVerbose) ? TraceEventType.Verbose : TraceEventType.Information;

            if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
            {
                Log(SpewVerbosity, "Run: " + App + " " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine));
            }
            ProcessResult Result = ProcessManager.CreateProcess(App, Options.HasFlag(ERunOptions.AllowSpew), Path.GetFileNameWithoutExtension(App), Env, SpewVerbosity: SpewVerbosity);
            Process       Proc   = Result.ProcessObject;

            bool bRedirectStdOut = (Options & ERunOptions.NoStdOutRedirect) != ERunOptions.NoStdOutRedirect;

            Proc.StartInfo.FileName        = App;
            Proc.StartInfo.Arguments       = String.IsNullOrEmpty(CommandLine) ? "" : CommandLine;
            Proc.StartInfo.UseShellExecute = false;
            if (bRedirectStdOut)
            {
                Proc.StartInfo.RedirectStandardOutput = true;
                Proc.StartInfo.RedirectStandardError  = true;
                Proc.OutputDataReceived += Result.StdOut;
                Proc.ErrorDataReceived  += Result.StdErr;
            }
            Proc.StartInfo.RedirectStandardInput = Input != null;
            Proc.StartInfo.CreateNoWindow        = true;
            if ((Options & ERunOptions.UTF8Output) == ERunOptions.UTF8Output)
            {
                Proc.StartInfo.StandardOutputEncoding = new System.Text.UTF8Encoding(false, false);
            }
            Proc.Start();

            if (bRedirectStdOut)
            {
                Proc.BeginOutputReadLine();
                Proc.BeginErrorReadLine();
            }

            if (String.IsNullOrEmpty(Input) == false)
            {
                Proc.StandardInput.WriteLine(Input);
                Proc.StandardInput.Close();
            }

            if (!Options.HasFlag(ERunOptions.NoWaitForExit))
            {
                Result.WaitForExit();
                var BuildDuration = (DateTime.UtcNow - StartTime).TotalMilliseconds;
                AddRunTime(App, (int)(BuildDuration));
                Result.ExitCode = Proc.ExitCode;
                if (!Options.HasFlag(ERunOptions.NoLoggingOfRunCommand))
                {
                    Log(SpewVerbosity, "Run: Took {0}s to run {1}, ExitCode={2}", BuildDuration / 1000, Path.GetFileName(App), Result.ExitCode);
                }
                Result.OnProcessExited();
                Result.DisposeProcess();
            }
            else
            {
                Result.ExitCode = -1;
            }

            return(Result);
        }
Esempio n. 2
0
        public static int Main()
        {
            // Parse the command line
            string[] Arguments = SharedUtils.ParseCommandLineAndRemoveExe(Environment.CommandLine);

            // Ensure UTF8Output flag is respected, since we are initializing logging early in the program.
            if (CommandUtils.ParseParam(Arguments, "-Utf8output"))
            {
                Console.OutputEncoding = new System.Text.UTF8Encoding(false, false);
            }

            // Parse the log level argument
            LogEventType LogLevel = LogEventType.Log;

            if (CommandUtils.ParseParam(Arguments, "-Verbose"))
            {
                LogLevel = LogEventType.Verbose;
            }
            if (CommandUtils.ParseParam(Arguments, "-VeryVerbose"))
            {
                LogLevel = LogEventType.VeryVerbose;
            }

            // Initialize the log system, buffering the output until we can create the log file
            StartupTraceListener StartupListener = new StartupTraceListener();

            Log.InitLogging(
                bLogTimestamps: CommandUtils.ParseParam(Arguments, "-Timestamps"),
                InLogLevel: LogLevel,
                bLogSeverity: true,
                bLogProgramNameWithSeverity: false,
                bLogSources: true,
                bLogSourcesToConsole: false,
                bColorConsoleOutput: true,
                TraceListeners: new TraceListener[]
            {
                StartupListener
            }
                );

            // Enter the main program section
            ExitCode ReturnCode = ExitCode.Success;

            try
            {
                // Set the working directory to the UE4 root
                Environment.CurrentDirectory = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetOriginalLocation()), "..", "..", ".."));

                // Ensure we can resolve any external assemblies as necessary.
                AssemblyUtils.InstallAssemblyResolver(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()));

                // Initialize the host platform layer
                HostPlatform.Initialize();

                // Log the operating environment. Since we usually compile to AnyCPU, we may be executed using different system paths under WOW64.
                Log.TraceVerbose("{2}: Running on {0} as a {1}-bit process.", HostPlatform.Current.GetType().Name, Environment.Is64BitProcess ? 64 : 32, DateTime.UtcNow.ToString("o"));

                // Log if we're running from the launcher
                string ExecutingAssemblyLocation = Assembly.GetExecutingAssembly().Location;
                if (string.Compare(ExecutingAssemblyLocation, Assembly.GetEntryAssembly().GetOriginalLocation(), StringComparison.OrdinalIgnoreCase) != 0)
                {
                    Log.TraceVerbose("Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
                }
                Log.TraceVerbose("CWD={0}", Environment.CurrentDirectory);

                // Hook up exit callbacks
                AppDomain Domain = AppDomain.CurrentDomain;
                Domain.ProcessExit  += Domain_ProcessExit;
                Domain.DomainUnload += Domain_ProcessExit;
                HostPlatform.Current.SetConsoleCtrlHandler(CtrlHandlerDelegateInstance);

                // Log the application version
                FileVersionInfo Version = AssemblyUtils.ExecutableVersion;
                Log.TraceVerbose("{0} ver. {1}", Version.ProductName, Version.ProductVersion);

                // Don't allow simultaneous execution of AT (in the same branch)
                ReturnCode = InternalUtils.RunSingleInstance(() => MainProc(Arguments, StartupListener));
            }
            catch (AutomationException Ex)
            {
                // Take the exit code from the exception
                Log.WriteException(Ex, LogUtils.FinalLogFileName);
                ReturnCode = Ex.ErrorCode;
            }
            catch (Exception Ex)
            {
                // Use a default exit code
                Log.WriteException(Ex, LogUtils.FinalLogFileName);
                ReturnCode = ExitCode.Error_Unknown;
            }
            finally
            {
                // In all cases, do necessary shut down stuff, but don't let any additional exceptions leak out while trying to shut down.

                // Make sure there's no directories on the stack.
                NoThrow(() => CommandUtils.ClearDirStack(), "Clear Dir Stack");

                // Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
                NoThrow(() => { if (ShouldKillProcesses && !Utils.IsRunningOnMono)
                                {
                                    ProcessManager.KillAll();
                                }
                        }, "Kill All Processes");

                // Write the exit code
                Log.TraceInformation("AutomationTool exiting with ExitCode={0} ({1})", (int)ReturnCode, ReturnCode);

                // Can't use NoThrow here because the code logs exceptions. We're shutting down logging!
                Trace.Close();
            }
            return((int)ReturnCode);
        }
Esempio n. 3
0
 /// <summary>
 /// Removes a process from the list of tracked processes.
 /// </summary>
 public void OnProcessExited()
 {
     ProcessManager.RemoveProcess(this);
 }
Esempio n. 4
0
        public static int Main()
        {
            var CommandLine = SharedUtils.ParseCommandLine();

            HostPlatform.Initialize();

            LogUtils.InitLogging(CommandLine);
            Log.WriteLine(TraceEventType.Information, "Running on {0}", HostPlatform.Current.GetType().Name);

            XmlConfigLoader.Init();

            // Log if we're running from the launcher
            var ExecutingAssemblyLocation = CommandUtils.CombinePaths(Assembly.GetExecutingAssembly().Location);

            if (String.Compare(ExecutingAssemblyLocation, CommandUtils.CombinePaths(InternalUtils.ExecutingAssemblyLocation), true) != 0)
            {
                Log.WriteLine(TraceEventType.Information, "Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
            }
            Log.WriteLine(TraceEventType.Information, "CWD={0}", Environment.CurrentDirectory);

            // Hook up exit callbacks
            var Domain = AppDomain.CurrentDomain;

            Domain.ProcessExit  += Domain_ProcessExit;
            Domain.DomainUnload += Domain_ProcessExit;
            HostPlatform.Current.SetConsoleCtrlHandler(ProgramCtrlHandler);

            var Version = InternalUtils.ExecutableVersion;

            Log.WriteLine(TraceEventType.Verbose, "{0} ver. {1}", Version.ProductName, Version.ProductVersion);

            try
            {
                // Don't allow simultaneous execution of AT (in the same branch)
                ReturnCode = InternalUtils.RunSingleInstance(MainProc, CommandLine);
            }
            catch (Exception Ex)
            {
                Log.WriteLine(TraceEventType.Error, "AutomationTool terminated with exception:");
                Log.WriteLine(TraceEventType.Error, LogUtils.FormatException(Ex));
                Log.WriteLine(TraceEventType.Error, Ex.Message);
                if (ReturnCode == 0)
                {
                    ReturnCode = (int)ErrorCodes.Error_Unknown;
                }
            }

            // Make sure there's no directiories on the stack.
            CommandUtils.ClearDirStack();
            Environment.ExitCode = ReturnCode;

            // Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
            if (ShouldKillProcesses)
            {
                ProcessManager.KillAll();
            }

            Log.WriteLine(TraceEventType.Information, "AutomationTool exiting with ExitCode={0}", ReturnCode);
            LogUtils.CloseFileLogging();

            return(ReturnCode);
        }