private void UnrealBinaryBuilderWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (bIsBuilding)
            {
                if (MessageBox.Show("AutomationTool is still running. Would you like to stop it and exit?", "Build in progress", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    if (AutomationToolProcess != null)
                    {
                        GameAnalyticsCSharp.AddDesignEvent("Build:AutomationTool:Killed:ExitProgram");
                        AutomationToolProcess.Kill();
                    }
                }
                else
                {
                    e.Cancel = true;
                    return;
                }
            }

            GameAnalyticsCSharp.EndSession();
            SaveAllSettings();

            postBuildSettings.Close();
            postBuildSettings = null;
            Application.Current.Shutdown();
        }
        private void AutomationToolBrowse_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog NewFileDialog = new OpenFileDialog
            {
                Filter = "exe file (*.exe)|*.exe"
            };

            ChangeStatusLabel(string.Format("Waiting for {0}.exe", AUTOMATION_TOOL_NAME));
            if (NewFileDialog.ShowDialog() == true)
            {
                AutomationExePath       = NewFileDialog.FileName;
                AutomationToolPath.Text = AutomationExePath;
                if (Path.GetFileNameWithoutExtension(AutomationExePath) == AUTOMATION_TOOL_NAME)
                {
                    BuildRocketUE.IsEnabled = true;
                    ChangeStatusLabel("Idle.");
                    FinalBuildPath = Path.GetFullPath(AutomationExePath).Replace(@"\Engine\Binaries\DotNET", @"\LocalBuilds\Engine").Replace(Path.GetFileName(AutomationExePath), "");
                    AddLogEntry(string.Format("Binary build can be found at: {0}", FinalBuildPath));
                }
                else
                {
                    GameAnalyticsCSharp.AddDesignEvent($"AutomationTool:IncorrectName:{Path.GetFileNameWithoutExtension(AutomationExePath)}");
                    ChangeStatusLabel("Error. Invalid automation tool file selected.");
                    MessageBox.Show("This is not Automation Tool Launcher. Please select AutomationToolLauncher.exe", "", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                return;
            }

            ChangeStatusLabel("Idle.");
        }
        private void CustomBuildXMLBrowse_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog NewFileDialog = new OpenFileDialog
            {
                Filter = "xml file (*.xml)|*.xml"
            };

            ChangeStatusLabel("Waiting for custom build file...");
            if (NewFileDialog.ShowDialog() == true)
            {
                CustomBuildXMLFile.Text = NewFileDialog.FileName;
                CustomOptions.IsEnabled = true;
                GameAnalyticsCSharp.AddDesignEvent($"BuildXML:Custom:{NewFileDialog.FileName}");
            }

            ChangeStatusLabel("Idle.");
        }
 public void TryShutdown()
 {
     if (bShutdownWindows.IsChecked == true)
     {
         if (bShutdownIfSuccess.IsChecked == true)
         {
             if (bLastBuildSuccess)
             {
                 GameAnalyticsCSharp.AddDesignEvent("Shutdown:BuildState:Success");
                 Internal_ShutdownWindows();
             }
             else
             {
                 GameAnalyticsCSharp.AddDesignEvent("Shutdown:BuildState:Failed");
             }
         }
         else
         {
             GameAnalyticsCSharp.AddDesignEvent("Shutdown:Started");
             Internal_ShutdownWindows();
         }
     }
 }
 private void CopyCommandLine_Click(object sender, RoutedEventArgs e)
 {
     GameAnalyticsCSharp.AddDesignEvent("CommandLine:CopyToClipboard");
     Clipboard.SetText(PrepareCommandline());
     MessageBox.Show("Commandline copied to clipboard!");
 }
 private void PostBuildSettings_Click(object sender, RoutedEventArgs e)
 {
     GameAnalyticsCSharp.AddDesignEvent("PostBuildSettings:Open");
     postBuildSettings.Owner = this;
     postBuildSettings.ShowDialog();
 }
        private void BuildRocketUE_Click(object sender, RoutedEventArgs e)
        {
            bLastBuildSuccess = false;

            if (bIsBuilding)
            {
                GameAnalyticsCSharp.AddDesignEvent("Build:AutomationTool:Killed");
                AutomationToolProcess.Kill();
                return;
            }

            if (FinalBuildPath == null && string.IsNullOrWhiteSpace(AutomationExePath) == false)
            {
                FinalBuildPath = Path.GetFullPath(AutomationExePath).Replace(@"\Engine\Binaries\DotNET", @"\LocalBuilds\Engine").Replace(Path.GetFileName(AutomationExePath), "");
            }

            if (Directory.Exists(FinalBuildPath))
            {
                MessageBoxResult MessageResult = MessageBox.Show($"Looks like an Engine build is already available at {FinalBuildPath}. Would you like to skip compiling the Engine and start zipping the existing build?\n\nPress Yes to Skip Engine build and start zipping (if enabled).\nPress No to continue with Engine Build.\nPress Cancel to do nothing.", "Zip Binary Version", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                switch (MessageResult)
                {
                case MessageBoxResult.Yes:
                    GameAnalyticsCSharp.AddDesignEvent("Build:EngineExists:FinishBuild");
                    // We don't want the system to shutdown since user is interacting.
                    bool?bOriginalShutdownState = bShutdownWindows.IsChecked;
                    bShutdownWindows.IsChecked = false;
                    OnBuildFinished(true);
                    bShutdownWindows.IsChecked = bOriginalShutdownState;
                    return;

                case MessageBoxResult.Cancel:
                    GameAnalyticsCSharp.AddDesignEvent("Build:EngineExists:Exit");
                    return;

                default:
                    GameAnalyticsCSharp.AddDesignEvent("Build:EngineExists:IgnoreAndContinue");
                    break;
                }
            }

            if (EngineVersionSelection.SelectedIndex == 0)
            {
                MessageBox.Show("Please select your Engine version to build. If you are unsure about the version number look into the following file:\n\n/Engine/Source/Runtime/Launch/Resources/Version.h\n\nAnd check ENGINE_MAJOR_VERSION and ENGINE_MINOR_VERSION.", "Select Engine Version.", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            ChangeStatusLabel("Preparing to build...");

            if (postBuildSettings.ShouldSaveToZip() && postBuildSettings.DirectoryIsWritable() == false)
            {
                GameAnalyticsCSharp.AddDesignEvent("Build:ZipEnabled:InvalidSetting");
                MessageBox.Show(string.Format("You chose to save Engine build as a zip file but below directory is either not available or not writable.\n\n{0}", postBuildSettings.ZipPath.Text), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (CustomBuildXMLFile.Text != DEFAULT_BUILD_XML_FILE)
            {
                if (CustomBuildXMLFile.Text == string.Empty)
                {
                    GameAnalyticsCSharp.LogEvent("Empty Build XML.", GameAnalyticsSDK.Net.EGAErrorSeverity.Error);
                    ChangeStatusLabel("Error. Empty build xml file.");
                    MessageBox.Show(string.Format("Build XML cannot be empty.\n\nIf you don't have a custom build file, press \"Reset to default\" to use default InstalledEngineBuild.xml", CustomBuildXMLFile.Text), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (File.Exists(CustomBuildXMLFile.Text) == false)
                {
                    GameAnalyticsCSharp.LogEvent("BuildXML does not exist.", GameAnalyticsSDK.Net.EGAErrorSeverity.Error);
                    ChangeStatusLabel("Error. Build xml does not exist.");
                    MessageBox.Show(string.Format("Build XML {0} does not exist!", CustomBuildXMLFile.Text), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            if (SupportHTML5() == false && bWithHTML5.IsChecked == true)
            {
                GameAnalyticsCSharp.AddDesignEvent($"Build:HTML5:IncorrectEngine:{GetEngineName()}");
                bWithHTML5.IsChecked = false;
                MessageBox.Show("HTML5 support was removed from Unreal Engine 4.24 and higher. You had it enabled but since it is of no use, I disabled it.");
            }

            if (SupportConsoles() == false && (bWithSwitch.IsChecked == true || bWithPS4.IsChecked == true || bWithXboxOne.IsChecked == true))
            {
                GameAnalyticsCSharp.AddDesignEvent($"Build:Console:IncorrectEngine:{GetEngineName()}");
                bWithSwitch.IsChecked = bWithPS4.IsChecked = bWithXboxOne.IsChecked = false;
                MessageBox.Show("Console support was removed from Unreal Engine 4.25 and higher. You had it enabled but since it is of no use, I disabled it.");
            }

            if (MessageBox.Show("You are going to build a binary version of Unreal Engine 4. This is a long process and might take time to finish. Are you sure you want to continue? ", "Build Binary Version", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                if (bWithDDC.IsChecked == true)
                {
                    MessageBoxResult MessageResult = MessageBox.Show("Building Derived Data Cache (DDC) is one of the slowest aspect of the build. You can skip this step if you want to. Do you want to continue with DDC enabled?\n\nPress Yes to continue with build\nPress No to continue without DDC\nPress Cancel to stop build", "Warning", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);

                    switch (MessageResult)
                    {
                    case MessageBoxResult.No:
                        bWithDDC.IsChecked = false;
                        GameAnalyticsCSharp.AddDesignEvent("Build:DDC:AutoDisabled");
                        break;

                    case MessageBoxResult.Cancel:
                        GameAnalyticsCSharp.AddDesignEvent("Build:DDC:Exit");
                        return;

                    default:
                        GameAnalyticsCSharp.AddDesignEvent("Build:DDC:IgnoreAndContinue");
                        break;
                    }
                }

                CompiledFiles = CompiledFilesTotal = 0;
                ProcessedFilesLabel.Content = "[Compiled: 0. Total: 0]";

                LogControl.ClearAllLogs();
                AddLogEntry(string.Format("Welcome to UE4 Binary Builder v{0}", PRODUCT_VERSION));
                BuildRocketUE.Content = "Stop Build";

                string CommandLineArgs = PrepareCommandline();

                ProcessStartInfo AutomationStartInfo = new ProcessStartInfo
                {
                    FileName               = AutomationExePath,
                    Arguments              = CommandLineArgs,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true
                };

                DispatchTimer.Start();
                StopwatchTimer.Start();

                AutomationToolProcess                     = new Process();
                AutomationToolProcess.StartInfo           = AutomationStartInfo;
                AutomationToolProcess.EnableRaisingEvents = true;
                AutomationToolProcess.OutputDataReceived += new DataReceivedEventHandler(AutomationToolProcess_OutputDataReceived);
                AutomationToolProcess.ErrorDataReceived  += new DataReceivedEventHandler(AutomationToolProcess_ErrorDataReceived);
                AutomationToolProcess.Exited             += new EventHandler(AutomationToolProcess_Exited);
                AutomationToolProcess.Start();
                AutomationToolProcess.BeginErrorReadLine();
                AutomationToolProcess.BeginOutputReadLine();

                bIsBuilding = true;
                ChangeStatusLabel("Building...");
                GameAnalyticsCSharp.AddDesignEvent("Build:Started");
            }
        }
        private string PrepareCommandline()
        {
            string BuildXMLFile = CustomBuildXMLFile.Text;

            if (BuildXMLFile != DEFAULT_BUILD_XML_FILE)
            {
                BuildXMLFile = string.Format("\"{0}\"", CustomBuildXMLFile.Text);
            }

            if (GameConfigurations.Text == "")
            {
                GameConfigurations.Text = "Development;Shipping";
                GameAnalyticsCSharp.AddDesignEvent("CommandLine:GameConfiguration:Reset");
            }

            string CommandLineArgs = string.Format("BuildGraph -target=\"Make Installed Build Win64\" -script={0} -set:WithDDC={1} -set:SignExecutables={2} -set:EmbedSrcSrvInfo={3} -set:GameConfigurations={4} -set:WithFullDebugInfo={5} -set:HostPlatformEditorOnly={6} -set:AnalyticsTypeOverride={7}",
                                                   BuildXMLFile,
                                                   GetConditionalString(bWithDDC.IsChecked),
                                                   GetConditionalString(bSignExecutables.IsChecked),
                                                   GetConditionalString(bEnableSymStore.IsChecked),
                                                   GameConfigurations.Text,
                                                   GetConditionalString(bWithFullDebugInfo.IsChecked),
                                                   GetConditionalString(bHostPlatformEditorOnly.IsChecked),
                                                   AnalyticsOverride.Text);

            if (bWithDDC.IsChecked == true && bHostPlatformDDCOnly.IsChecked == true)
            {
                CommandLineArgs += " -set:HostPlatformDDCOnly=true";
            }

            if (bHostPlatformOnly.IsChecked == true)
            {
                CommandLineArgs += " -set:HostPlatformOnly=true";
                GameAnalyticsCSharp.AddDesignEvent("CommandLine:HostOnly");
            }
            else
            {
                CommandLineArgs += string.Format(" -set:WithWin64={0} -set:WithWin32={1} -set:WithMac={2} -set:WithAndroid={3} -set:WithIOS={4} -set:WithTVOS={5} -set:WithLinux={6} -set:WithLumin={7}",
                                                 GetConditionalString(bWithWin64.IsChecked),
                                                 GetConditionalString(bWithWin32.IsChecked),
                                                 GetConditionalString(bWithMac.IsChecked),
                                                 GetConditionalString(bWithAndroid.IsChecked),
                                                 GetConditionalString(bWithIOS.IsChecked),
                                                 GetConditionalString(bWithTVOS.IsChecked),
                                                 GetConditionalString(bWithLinux.IsChecked),
                                                 GetConditionalString(bWithLumin.IsChecked));

                if (SupportHTML5())
                {
                    CommandLineArgs += string.Format(" -set:WithHTML5={0}",
                                                     GetConditionalString(bWithHTML5.IsChecked));
                }

                if (SupportConsoles())
                {
                    CommandLineArgs += string.Format(" -set:WithSwitch={0} -set:WithPS4={1} -set:WithXboxOne={2}",
                                                     GetConditionalString(bWithSwitch.IsChecked),
                                                     GetConditionalString(bWithPS4.IsChecked),
                                                     GetConditionalString(bWithXboxOne.IsChecked));
                }

                if (SupportLinuxAArch64())
                {
                    CommandLineArgs += string.Format(" -set:WithLinuxAArch64={0}", GetConditionalString(bWithLinuxAArch64.IsChecked));
                }
            }

            if (IsEngineSelection425OrAbove())
            {
                CommandLineArgs += string.Format(" -set:CompileDatasmithPlugins={0} -set:VS2019={1}",
                                                 GetConditionalString(bCompileDatasmithPlugins.IsChecked),
                                                 GetConditionalString(bVS2019.IsChecked));
            }

            if (EngineVersionSelection.SelectedIndex > 1)
            {
                CommandLineArgs += string.Format(" -set:WithServer={0} -set:WithClient={1} -set:WithHoloLens={2}",
                                                 GetConditionalString(bWithServer.IsChecked),
                                                 GetConditionalString(bWithClient.IsChecked),
                                                 GetConditionalString(bWithHoloLens.IsChecked));
            }

            if (BuildXMLFile != DEFAULT_BUILD_XML_FILE && CustomOptions.Text != string.Empty)
            {
                CommandLineArgs += string.Format(" {0}", CustomOptions.Text);
                AddLogEntry("Using custom options...");
                GameAnalyticsCSharp.AddDesignEvent("CommandLine:UsingCustomOptions");
            }

            if (bCleanBuild.IsChecked == true)
            {
                CommandLineArgs += " -Clean";
                GameAnalyticsCSharp.AddDesignEvent("CommandLine:CleanEnabled");
            }

            return(CommandLineArgs);
        }
 private void ResetDefaultBuildXML_Click(object sender, RoutedEventArgs e)
 {
     CustomBuildXMLFile.Text = DEFAULT_BUILD_XML_FILE;
     CustomOptions.IsEnabled = false;
     GameAnalyticsCSharp.AddDesignEvent("BuildXML:ResetToDefault");
 }
 private void GetSourceCodeMenu_Click(object sender, RoutedEventArgs e)
 {
     GameAnalyticsCSharp.AddDesignEvent("GetSourceCode:Open");
     Process.Start("https://github.com/ryanjon2040/UE4-Binary-Builder");
 }
 private void AboutMenu_Click(object sender, RoutedEventArgs e)
 {
     AboutDialog.IsOpen = true;
     GameAnalyticsCSharp.AddDesignEvent("AboutDialog:Open");
 }
 private void AboutBtn_Ok_Click(object sender, RoutedEventArgs e)
 {
     AboutDialog.IsOpen = false;
     GameAnalyticsCSharp.AddDesignEvent("AboutDialog:Close");
 }