public IAppInstall InstallApplication(UnrealAppConfig AppConfig)
        {
            if (AppConfig.Build is StagedBuild)
            {
                return(InstallStagedBuild(AppConfig, AppConfig.Build as StagedBuild));
            }

            EditorBuild EditorBuild = AppConfig.Build as EditorBuild;

            if (EditorBuild == null)
            {
                throw new AutomationException("Invalid build type!");
            }

            WindowsAppInstall WinApp = new WindowsAppInstall(AppConfig.Name, AppConfig.ProjectName, this);

            WinApp.WorkingDirectory = Path.GetDirectoryName(EditorBuild.ExecutablePath);
            WinApp.RunOptions       = RunOptions;

            // Force this to stop logs and other artifacts going to different places
            WinApp.CommandArguments = AppConfig.CommandLine + string.Format(" -userdir=\"{0}\"", UserDir);
            WinApp.ArtifactPath     = Path.Combine(UserDir, @"Saved");
            WinApp.ExecutablePath   = EditorBuild.ExecutablePath;

            return(WinApp);
        }
        public IAppInstance Run(IAppInstall App)
        {
            WindowsAppInstall WinApp = App as WindowsAppInstall;

            if (WinApp == null)
            {
                throw new DeviceException("AppInstance is of incorrect type!");
            }

            if (File.Exists(WinApp.ExecutablePath) == false)
            {
                throw new DeviceException("Specified path {0} not found!", WinApp.ExecutablePath);
            }

            IProcessResult Result = null;

            lock (Globals.MainLock)
            {
                string ExePath       = Path.GetDirectoryName(WinApp.ExecutablePath);
                string NewWorkingDir = string.IsNullOrEmpty(WinApp.WorkingDirectory) ? ExePath : WinApp.WorkingDirectory;
                string OldWD         = Environment.CurrentDirectory;
                Environment.CurrentDirectory = NewWorkingDir;

                Log.Info("Launching {0} on {1}", App.Name, ToString());
                Log.Verbose("\t{0}", WinApp.CommandArguments);

                Result = CommandUtils.Run(WinApp.ExecutablePath, WinApp.CommandArguments, Options: WinApp.RunOptions);

                if (Result.HasExited && Result.ExitCode != 0)
                {
                    throw new AutomationException("Failed to launch {0}. Error {1}", WinApp.ExecutablePath, Result.ExitCode);
                }

                Environment.CurrentDirectory = OldWD;
            }

            return(new WindowsAppInstance(WinApp, Result));
        }
        protected IAppInstall InstallStagedBuild(UnrealAppConfig AppConfig, StagedBuild InBuild)
        {
            bool SkipDeploy = Globals.Params.ParseParam("SkipDeploy");

            string BuildPath = InBuild.BuildPath;

            if (CanRunFromPath(BuildPath) == false)
            {
                string SubDir   = string.IsNullOrEmpty(AppConfig.Sandbox) ? AppConfig.ProjectName : AppConfig.Sandbox;
                string DestPath = Path.Combine(this.TempDir, SubDir, AppConfig.ProcessType.ToString());

                if (!SkipDeploy)
                {
                    StagedBuild.InstallBuildParallel(AppConfig, InBuild, BuildPath, DestPath, ToString());
                }
                else
                {
                    Log.Info("Skipping install of {0} (-skipdeploy)", BuildPath);
                }

                Utils.SystemHelpers.MarkDirectoryForCleanup(DestPath);

                BuildPath = DestPath;
            }

            WindowsAppInstall WinApp = new WindowsAppInstall(AppConfig.Name, AppConfig.ProjectName, this);

            WinApp.RunOptions = RunOptions;

            // Set commandline replace any InstallPath arguments with the path we use
            WinApp.CommandArguments = Regex.Replace(AppConfig.CommandLine, @"\$\(InstallPath\)", BuildPath, RegexOptions.IgnoreCase);

            if (string.IsNullOrEmpty(UserDir) == false)
            {
                WinApp.CommandArguments += string.Format(" -userdir=\"{0}\"", UserDir);
                WinApp.ArtifactPath      = Path.Combine(UserDir, @"Saved");

                Utils.SystemHelpers.MarkDirectoryForCleanup(UserDir);
            }
            else
            {
                // e.g d:\Unreal\GameName\Saved
                WinApp.ArtifactPath = Path.Combine(BuildPath, AppConfig.ProjectName, @"Saved");
            }

            // clear artifact path
            if (Directory.Exists(WinApp.ArtifactPath))
            {
                try
                {
                    Directory.Delete(WinApp.ArtifactPath, true);
                }
                catch (Exception Ex)
                {
                    Log.Warning("Failed to delete {0}. {1}", WinApp.ArtifactPath, Ex.Message);
                }
            }

            if (LocalDirectoryMappings.Count == 0)
            {
                PopulateDirectoryMappings(Path.Combine(BuildPath, AppConfig.ProjectName), UserDir);
            }

            if (AppConfig.FilesToCopy != null)
            {
                foreach (UnrealFileToCopy FileToCopy in AppConfig.FilesToCopy)
                {
                    string PathToCopyTo = Path.Combine(LocalDirectoryMappings[FileToCopy.TargetBaseDirectory], FileToCopy.TargetRelativeLocation);
                    if (File.Exists(FileToCopy.SourceFileLocation))
                    {
                        FileInfo SrcInfo = new FileInfo(FileToCopy.SourceFileLocation);
                        SrcInfo.IsReadOnly = false;
                        string DirectoryToCopyTo = Path.GetDirectoryName(PathToCopyTo);
                        if (!Directory.Exists(DirectoryToCopyTo))
                        {
                            Directory.CreateDirectory(DirectoryToCopyTo);
                        }
                        if (File.Exists(PathToCopyTo))
                        {
                            FileInfo ExistingFile = new FileInfo(PathToCopyTo);
                            ExistingFile.IsReadOnly = false;
                        }
                        SrcInfo.CopyTo(PathToCopyTo, true);
                        Log.Info("Copying {0} to {1}", FileToCopy.SourceFileLocation, PathToCopyTo);
                    }
                    else
                    {
                        Log.Warning("File to copy {0} not found", FileToCopy);
                    }
                }
            }

            if (Path.IsPathRooted(InBuild.ExecutablePath))
            {
                WinApp.ExecutablePath = InBuild.ExecutablePath;
            }
            else
            {
                // TODO - this check should be at a higher level....
                string BinaryPath = Path.Combine(BuildPath, InBuild.ExecutablePath);

                // check for a local newer executable
                if (Globals.Params.ParseParam("dev") && AppConfig.ProcessType.UsesEditor() == false)
                {
                    string LocalBinary = Path.Combine(Environment.CurrentDirectory, InBuild.ExecutablePath);

                    bool LocalFileExists = File.Exists(LocalBinary);
                    bool LocalFileNewer  = LocalFileExists && File.GetLastWriteTime(LocalBinary) > File.GetLastWriteTime(BinaryPath);

                    Log.Verbose("Checking for newer binary at {0}", LocalBinary);
                    Log.Verbose("LocalFile exists: {0}. Newer: {1}", LocalFileExists, LocalFileNewer);

                    if (LocalFileExists && LocalFileNewer)
                    {
                        // need to -basedir to have our exe load content from the path
                        WinApp.CommandArguments += string.Format(" -basedir={0}", Path.GetDirectoryName(BinaryPath));

                        BinaryPath = LocalBinary;
                    }
                }

                WinApp.ExecutablePath = BinaryPath;
            }

            return(WinApp);
        }
        public IAppInstance Run(IAppInstall App)
        {
            WindowsAppInstall WinApp = App as WindowsAppInstall;

            if (WinApp == null)
            {
                throw new DeviceException("AppInstance is of incorrect type!");
            }

            if (File.Exists(WinApp.ExecutablePath) == false)
            {
                throw new DeviceException("Specified path {0} not found!", WinApp.ExecutablePath);
            }

            IProcessResult Result         = null;
            string         ProcessLogFile = null;

            lock (Globals.MainLock)
            {
                string ExePath       = Path.GetDirectoryName(WinApp.ExecutablePath);
                string NewWorkingDir = string.IsNullOrEmpty(WinApp.WorkingDirectory) ? ExePath : WinApp.WorkingDirectory;
                string OldWD         = Environment.CurrentDirectory;
                Environment.CurrentDirectory = NewWorkingDir;

                Log.Info("Launching {0} on {1}", App.Name, ToString());

                string CmdLine = WinApp.CommandArguments;

                // Look in app parameters if abslog is specified, if so use it
                Regex CLRegex = new Regex(@"(--?[a-zA-Z]+)[:\s=]?([A-Z]:(?:\\[\w\s-]+)+\\?(?=\s-)|\""[^\""]*\""|[^-][^\s]*)?");
                foreach (Match M in CLRegex.Matches(CmdLine))
                {
                    if (M.Groups.Count == 3 && M.Groups[1].Value == "-abslog")
                    {
                        ProcessLogFile = M.Groups[2].Value;
                    }
                }

                // explicitly set log file when not already defined
                if (string.IsNullOrEmpty(ProcessLogFile))
                {
                    string LogFolder = string.Format(@"{0}\Logs", WinApp.ArtifactPath);

                    if (!Directory.Exists(LogFolder))
                    {
                        Directory.CreateDirectory(LogFolder);
                    }

                    ProcessLogFile = string.Format("{0}\\{1}.log", LogFolder, WinApp.ProjectName);
                    CmdLine        = string.Format("{0} -abslog=\"{1}\"", CmdLine, ProcessLogFile);
                }

                // cleanup any existing log file
                try
                {
                    if (File.Exists(ProcessLogFile))
                    {
                        File.Delete(ProcessLogFile);
                    }
                }
                catch (Exception Ex)
                {
                    throw new AutomationException("Unable to delete existing log file {0} {1}", ProcessLogFile, Ex.Message);
                }

                Log.Verbose("\t{0}", CmdLine);

                Result = CommandUtils.Run(WinApp.ExecutablePath, CmdLine, Options: WinApp.RunOptions | (ProcessLogFile != null ? CommandUtils.ERunOptions.NoStdOutRedirect : 0));

                if (Result.HasExited && Result.ExitCode != 0)
                {
                    throw new AutomationException("Failed to launch {0}. Error {1}", WinApp.ExecutablePath, Result.ExitCode);
                }

                Environment.CurrentDirectory = OldWD;
            }

            return(new WindowsAppInstance(WinApp, Result, ProcessLogFile));
        }
 public WindowsAppInstance(WindowsAppInstall InInstall, IProcessResult InProcess, string ProcessLogFile = null)
     : base(InProcess, InInstall.CommandArguments, ProcessLogFile)
 {
     Install = InInstall;
 }
 public WindowsAppInstance(WindowsAppInstall InInstall, IProcessResult InProcess)
     : base(InProcess, InInstall.CommandArguments)
 {
     Install = InInstall;
 }