From ac7ef119e0805b8468b1735a47b6aaef7f33c8fb Mon Sep 17 00:00:00 2001
From: rbalsleyMSFT <53497092+rbalsleyMSFT@users.noreply.github.com>
Date: Mon, 4 Aug 2025 17:21:34 -0700
Subject: [PATCH] Feat: Add option to ignore non-zero application exit codes
Introduces a new feature allowing application installations to succeed regardless of their exit code. This is useful for installers that may return non-standard exit codes which should be treated as successful.
Changes include:
- A new checkbox in the UI to enable this option for an application.
- Updates to the application installation script to handle the new setting.
- Modifications to save and load this setting in the application list.
---
.../Apps/Orchestration/Install-Win32Apps.ps1 | 18 +++++++--
FFUDevelopment/BuildFFUVM_UI.xaml | 4 ++
.../FFUUI.Core/FFUUI.Core.Applications.psm1 | 37 ++++++++++++++-----
.../FFUUI.Core/FFUUI.Core.Initialize.psm1 | 1 +
4 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/FFUDevelopment/Apps/Orchestration/Install-Win32Apps.ps1 b/FFUDevelopment/Apps/Orchestration/Install-Win32Apps.ps1
index cf70a44..83c0a9b 100644
--- a/FFUDevelopment/Apps/Orchestration/Install-Win32Apps.ps1
+++ b/FFUDevelopment/Apps/Orchestration/Install-Win32Apps.ps1
@@ -15,8 +15,10 @@ function Invoke-Process {
[bool]$Wait = $true,
[Parameter()]
- [string[]]$AdditionalSuccessCodes
+ [string[]]$AdditionalSuccessCodes,
+ [Parameter()]
+ [bool]$IgnoreNonZeroExitCodes = $false
)
$ErrorActionPreference = 'Stop'
@@ -51,8 +53,12 @@ function Invoke-Process {
$exitCode = $p.ExitCode
# An exit code of 0 is always a success
if ($exitCode -ne 0) {
+ # If IgnoreNonZeroExitCodes is true, treat any non-zero exit code as a success
+ if ($IgnoreNonZeroExitCodes) {
+ Write-Host "Ignoring non-zero exit code $exitCode because IgnoreNonZeroExitCodes is set to true."
+ }
# Check if the non-zero exit code is in the list of additional success codes
- if ($null -eq $AdditionalSuccessCodes -or $exitCode -notin $AdditionalSuccessCodes) {
+ elseif ($null -eq $AdditionalSuccessCodes -or $exitCode -notin $AdditionalSuccessCodes) {
if ($cmdError) {
throw $cmdError.Trim()
}
@@ -152,8 +158,14 @@ function Install-Applications {
Write-Host "Additional success exit codes for $($app.Name): $($additionalSuccessCodes -join ', ')"
}
+ # Check for IgnoreNonZeroExitCodes
+ $ignoreNonZeroExitCodes = $false
+ if ($app.PSObject.Properties['IgnoreNonZeroExitCodes'] -and $app.IgnoreNonZeroExitCodes -is [bool]) {
+ $ignoreNonZeroExitCodes = $app.IgnoreNonZeroExitCodes
+ }
+
Write-Host "Running command: $($app.CommandLine) $($argumentsToPass -join ' ')"
- $result = Invoke-Process -FilePath $($app.CommandLine) -ArgumentList $argumentsToPass -AdditionalSuccessCodes $additionalSuccessCodes
+ $result = Invoke-Process -FilePath $($app.CommandLine) -ArgumentList $argumentsToPass -AdditionalSuccessCodes $additionalSuccessCodes -IgnoreNonZeroExitCodes $ignoreNonZeroExitCodes
Write-Host "$($app.Name) exited with exit code: $($result.ExitCode)`r`n"
} catch {
Write-Error "Error occurred while installing $($app.Name): $_"
diff --git a/FFUDevelopment/BuildFFUVM_UI.xaml b/FFUDevelopment/BuildFFUVM_UI.xaml
index a1e733a..fa3ebe9 100644
--- a/FFUDevelopment/BuildFFUVM_UI.xaml
+++ b/FFUDevelopment/BuildFFUVM_UI.xaml
@@ -377,6 +377,9 @@
+
+
+
@@ -397,6 +400,7 @@
+
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Applications.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Applications.psm1
index 38749a7..5b11ab6 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Applications.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Applications.psm1
@@ -56,6 +56,7 @@ function Add-BYOApplication {
$arguments = $State.Controls.txtAppArguments.Text
$source = $State.Controls.txtAppSource.Text
$additionalExitCodes = $State.Controls.txtAppAdditionalExitCodes.Text
+ $ignoreNonZeroExitCodes = $State.Controls.chkIgnoreExitCodes.IsChecked
if ([string]::IsNullOrWhiteSpace($name) -or [string]::IsNullOrWhiteSpace($commandLine)) {
[System.Windows.MessageBox]::Show("Please fill in all fields (Name and Command Line)", "Missing Information", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
@@ -72,13 +73,24 @@ function Add-BYOApplication {
if ($listView.Items.Count -gt 0) {
$priority = ($listView.Items | Measure-Object -Property Priority -Maximum).Maximum + 1
}
- $application = [PSCustomObject]@{ Priority = $priority; Name = $name; CommandLine = $commandLine; Arguments = $arguments; Source = $source; AdditionalExitCodes = $additionalExitCodes; CopyStatus = "" }
+ $application = [PSCustomObject]@{
+ Priority = $priority
+ Name = $name
+ CommandLine = $commandLine
+ Arguments = $arguments
+ Source = $source
+ AdditionalExitCodes = $additionalExitCodes
+ IgnoreNonZeroExitCodes = $ignoreNonZeroExitCodes
+ IgnoreExitCodes = if ($ignoreNonZeroExitCodes) { "Yes" } else { "No" }
+ CopyStatus = ""
+ }
$listView.Items.Add($application)
$State.Controls.txtAppName.Text = ""
$State.Controls.txtAppCommandLine.Text = ""
$State.Controls.txtAppArguments.Text = ""
$State.Controls.txtAppSource.Text = ""
$State.Controls.txtAppAdditionalExitCodes.Text = ""
+ $State.Controls.chkIgnoreExitCodes.IsChecked = $false
Update-CopyButtonState -State $State
}
@@ -162,8 +174,10 @@ function Save-BYOApplicationList {
try {
# Ensure items are sorted by current priority before saving
- # Exclude CopyStatus when saving and ensure Priority is an integer
- $applications = $listView.Items | Sort-Object Priority | Select-Object @{N = 'Priority'; E = { [int]$_.Priority } }, Name, CommandLine, Arguments, Source, AdditionalExitCodes
+ # Exclude UI-only properties (CopyStatus, IgnoreExitCodes) and ensure Priority is an integer
+ $propertiesToSave = 'Priority', 'Name', 'CommandLine', 'Arguments', 'Source', 'AdditionalExitCodes', 'IgnoreNonZeroExitCodes'
+ $applications = $listView.Items | Sort-Object Priority | Select-Object @{N = 'Priority'; E = { [int]$_.Priority } }, Name, CommandLine, Arguments, Source, AdditionalExitCodes, IgnoreNonZeroExitCodes
+
$applications | ConvertTo-Json -Depth 5 | Set-Content -Path $Path -Force -Encoding UTF8
[System.Windows.MessageBox]::Show("Applications saved successfully to `"$Path`".", "Save Applications", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
}
@@ -195,14 +209,17 @@ function Import-BYOApplicationList {
# Add items and sort by priority from the file
$sortedApps = $applications | Sort-Object Priority
foreach ($app in $sortedApps) {
+ $ignoreNonZero = if ($app.PSObject.Properties['IgnoreNonZeroExitCodes']) { $app.IgnoreNonZeroExitCodes } else { $false }
$appObject = [PSCustomObject]@{
- Priority = $app.Priority
- Name = $app.Name
- CommandLine = $app.CommandLine
- Arguments = if ($app.PSObject.Properties['Arguments']) { $app.Arguments } else { "" }
- Source = $app.Source
- AdditionalExitCodes = if ($app.PSObject.Properties['AdditionalExitCodes']) { $app.AdditionalExitCodes } else { "" }
- CopyStatus = ""
+ Priority = $app.Priority
+ Name = $app.Name
+ CommandLine = $app.CommandLine
+ Arguments = if ($app.PSObject.Properties['Arguments']) { $app.Arguments } else { "" }
+ Source = $app.Source
+ AdditionalExitCodes = if ($app.PSObject.Properties['AdditionalExitCodes']) { $app.AdditionalExitCodes } else { "" }
+ IgnoreNonZeroExitCodes = $ignoreNonZero
+ IgnoreExitCodes = if ($ignoreNonZero) { "Yes" } else { "No" }
+ CopyStatus = ""
}
$listView.Items.Add($appObject)
}
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
index 6938da3..3460ac1 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
@@ -90,6 +90,7 @@ function Initialize-UIControls {
$State.Controls.txtAppArguments = $window.FindName('txtAppArguments')
$State.Controls.txtAppSource = $window.FindName('txtAppSource')
$State.Controls.txtAppAdditionalExitCodes = $window.FindName('txtAppAdditionalExitCodes')
+ $State.Controls.chkIgnoreExitCodes = $window.FindName('chkIgnoreExitCodes')
$State.Controls.btnAddApplication = $window.FindName('btnAddApplication')
$State.Controls.btnSaveBYOApplications = $window.FindName('btnSaveBYOApplications')
$State.Controls.btnLoadBYOApplications = $window.FindName('btnLoadBYOApplications')