diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 4d7fbd2..a6d2b6e 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -354,6 +354,8 @@ param( [bool]$BuildUSBDrive, [hashtable]$USBDriveList, [int]$MaxUSBDrives = 5, + [ValidateSet('Foreground', 'High', 'Normal', 'Low')] + [string]$BitsPriority = 'Normal', [Parameter(Mandatory = $false)] [ValidateSet(10, 11, 2016, 2019, 2021, 2022, 2024, 2025)] [int]$WindowsRelease = 11, @@ -659,6 +661,7 @@ if ($WindowsSKU -like "*LTS*") { # Set the log path for the common logger Set-CommonCoreLogPath -Path $LogFile +Set-BitsTransferPriority -Priority $BitsPriority #FUNCTIONS diff --git a/FFUDevelopment/BuildFFUVM_UI.xaml b/FFUDevelopment/BuildFFUVM_UI.xaml index cf20f8e..d9884d6 100644 --- a/FFUDevelopment/BuildFFUVM_UI.xaml +++ b/FFUDevelopment/BuildFFUVM_UI.xaml @@ -641,7 +641,7 @@ - + @@ -657,13 +657,15 @@ - + - + - + - + + + @@ -729,11 +731,25 @@ - - + + + + + + + + + Foreground + High + Normal + Low + + + + - - + + @@ -745,8 +761,8 @@ - - + + @@ -811,8 +827,8 @@ - - + + diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 index 30a3dd2..0b2a564 100644 --- a/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 +++ b/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 @@ -12,6 +12,10 @@ $script:CommonCoreLogFilePath = $null # Mutex for log file access $script:commonCoreLogMutexName = "Global\FFUCommonCoreLogMutex" # Unique name $script:commonCoreLogMutex = New-Object System.Threading.Mutex($false, $script:commonCoreLogMutexName) +$script:BitsTransferPriority = 'Normal' +if (-not [string]::IsNullOrWhiteSpace($env:FFU_BITS_PRIORITY)) { + $script:BitsTransferPriority = $env:FFU_BITS_PRIORITY +} # Function to set the log file path for this module function Set-CommonCoreLogPath { @@ -30,7 +34,24 @@ function Set-CommonCoreLogPath { Write-Warning "Set-CommonCoreLogPath called with an empty or null path." } } - + +function Set-BitsTransferPriority { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [ValidateSet('Foreground', 'High', 'Normal', 'Low')] + [string]$Priority + ) + $script:BitsTransferPriority = $Priority + try { + Set-Item -Path Env:FFU_BITS_PRIORITY -Value $Priority -ErrorAction Stop + } + catch { + WriteLog "Failed to set FFU_BITS_PRIORITY environment variable: $($_.Exception.Message)" + } + WriteLog "BITS transfer priority set to $Priority." +} + # Centralized WriteLog function function WriteLog { [CmdletBinding()] @@ -143,9 +164,23 @@ function Start-BitsTransferWithRetry { [string]$Source, [Parameter(Mandatory = $true)] [string]$Destination, - [int]$Retries = 3 + [int]$Retries = 3, + [ValidateSet('Foreground','High','Normal','Low')] + [string]$Priority ) + if ([string]::IsNullOrWhiteSpace($Priority)) { + if (-not [string]::IsNullOrWhiteSpace($env:FFU_BITS_PRIORITY)) { + $Priority = $env:FFU_BITS_PRIORITY + } + elseif (-not [string]::IsNullOrWhiteSpace($script:BitsTransferPriority)) { + $Priority = $script:BitsTransferPriority + } + else { + $Priority = 'Normal' + } + } + $attempt = 0 $lastError = $null $notLoggedOnHResult = [int]0x800704dd @@ -158,7 +193,7 @@ function Start-BitsTransferWithRetry { $VerbosePreference = 'SilentlyContinue' $ProgressPreference = 'SilentlyContinue' - Start-BitsTransfer -Source $Source -Destination $Destination -Priority Normal -ErrorAction Stop + Start-BitsTransfer -Source $Source -Destination $Destination -Priority $Priority -ErrorAction Stop $ProgressPreference = $OriginalProgressPreference $VerbosePreference = $OriginalVerbosePreference @@ -259,7 +294,7 @@ function ConvertTo-SafeName { # Collapse multiple consecutive dashes $sanitized = $sanitized -replace '-{2,}', '-' # Trim leading/trailing spaces, periods, and dashes - $sanitized = $sanitized.Trim(' ','.','-') + $sanitized = $sanitized.Trim(' ', '.', '-') if ([string]::IsNullOrWhiteSpace($sanitized)) { $sanitized = 'Unnamed' } diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 index 5105b99..13cc782 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 @@ -96,6 +96,7 @@ function Get-UIConfig { USBDriveList = @{} Username = $State.Controls.txtUsername.Text Threads = [int]$State.Controls.txtThreads.Text + BitsPriority = $State.Controls.cmbBitsPriority.SelectedItem MaxUSBDrives = [int]$State.Controls.txtMaxUSBDrives.Text Verbose = $State.Controls.chkVerbose.IsChecked VMHostIPAddress = $State.Controls.txtVMHostIPAddress.Text @@ -412,6 +413,7 @@ function Update-UIFromConfig { Set-UIValue -ControlName 'txtShareName' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'ShareName' -State $State Set-UIValue -ControlName 'txtUsername' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'Username' -State $State Set-UIValue -ControlName 'txtThreads' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'Threads' -State $State + Set-UIValue -ControlName 'cmbBitsPriority' -PropertyName 'SelectedItem' -ConfigObject $ConfigContent -ConfigKey 'BitsPriority' -State $State Set-UIValue -ControlName 'txtMaxUSBDrives' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'MaxUSBDrives' -State $State Set-UIValue -ControlName 'chkBuildUSBDriveEnable' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'BuildUSBDrive' -State $State Set-UIValue -ControlName 'chkCompactOS' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CompactOS' -State $State @@ -748,13 +750,14 @@ function Update-UIFromConfig { else { $State.Controls.additionalFFUPanel.Visibility = 'Collapsed' } + } + catch { + WriteLog "LoadConfig: Error applying Additional FFU selections: $($_.Exception.Message)" + } + + Update-BitsPrioritySetting -State $State + WriteLog "LoadConfig: Configuration loading process finished." } - catch { - WriteLog "LoadConfig: Error applying Additional FFU selections: $($_.Exception.Message)" - } - - WriteLog "LoadConfig: Configuration loading process finished." - } function Invoke-SaveConfiguration { param( diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 index 5043d43..e739fb6 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 @@ -152,6 +152,17 @@ function Register-EventHandlers { $localState.Controls.chkPromptExternalHardDiskMedia.IsChecked = $false }) + if ($null -ne $State.Controls.cmbBitsPriority) { + $State.Controls.cmbBitsPriority.Add_SelectionChanged({ + param($eventSource, $selectionChangedEventArgs) + $window = [System.Windows.Window]::GetWindow($eventSource) + if ($null -eq $window -or $null -eq $window.Tag) { + return + } + Update-BitsPrioritySetting -State $window.Tag + }) + } + # Additional FFU Files events $State.Controls.chkCopyAdditionalFFUFiles.Add_Checked({ param($eventSource, $routedEventArgs) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 index 0870af7..f18eec3 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 @@ -118,6 +118,7 @@ function Initialize-UIControls { $State.Controls.txtShareName = $window.FindName('txtShareName') $State.Controls.txtUsername = $window.FindName('txtUsername') $State.Controls.txtThreads = $window.FindName('txtThreads') + $State.Controls.cmbBitsPriority = $window.FindName('cmbBitsPriority') $State.Controls.txtMaxUSBDrives = $window.FindName('txtMaxUSBDrives') $State.Controls.chkCompactOS = $window.FindName('chkCompactOS') $State.Controls.chkOptimize = $window.FindName('chkOptimize') @@ -234,6 +235,7 @@ function Initialize-UIDefaults { $State.Controls.txtShareName.Text = $State.Defaults.generalDefaults.ShareName $State.Controls.txtUsername.Text = $State.Defaults.generalDefaults.Username $State.Controls.txtThreads.Text = $State.Defaults.generalDefaults.Threads + $State.Controls.cmbBitsPriority.SelectedItem = $State.Defaults.generalDefaults.BitsPriority $State.Controls.txtMaxUSBDrives.Text = $State.Defaults.generalDefaults.MaxUSBDrives $State.Controls.chkBuildUSBDriveEnable.IsChecked = $State.Defaults.generalDefaults.BuildUSBDriveEnable $State.Controls.chkCompactOS.IsChecked = $State.Defaults.generalDefaults.CompactOS @@ -263,6 +265,7 @@ function Initialize-UIDefaults { $State.Controls.chkPromptExternalHardDiskMedia.IsEnabled = $State.Controls.chkAllowExternalHardDiskMedia.IsChecked $State.Controls.chkCopyAdditionalFFUFiles.IsChecked = $State.Defaults.generalDefaults.CopyAdditionalFFUFiles $State.Controls.additionalFFUPanel.Visibility = if ($State.Controls.chkCopyAdditionalFFUFiles.IsChecked) { 'Visible' } else { 'Collapsed' } + Update-BitsPrioritySetting -State $State # Hyper-V Settings defaults from General Defaults Initialize-VMSwitchData -State $State diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 index 4299e06..0914251 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Shared.psm1 @@ -220,6 +220,32 @@ function Invoke-ProgressUpdate { $ProgressQueue.Enqueue(@{ Identifier = $Identifier; Status = $Status }) } +function Update-BitsPrioritySetting { + param( + [Parameter(Mandatory)] + [pscustomobject]$State + ) + + $combo = $State.Controls.cmbBitsPriority + if ($null -eq $combo) { + WriteLog "BITS priority control not available; skipping priority update." + return + } + + $selectedPriority = $combo.SelectedItem + if ([string]::IsNullOrWhiteSpace($selectedPriority)) { + $selectedPriority = 'Normal' + } + + try { + Set-BitsTransferPriority -Priority $selectedPriority + WriteLog "BITS transfer priority set to $selectedPriority." + } + catch { + WriteLog "Failed to set BITS transfer priority: $($_.Exception.Message)" + } +} + # Add a function to create a sortable list view function Add-SortableColumn { param( diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 index b4bc6d3..ebc20ed 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 @@ -117,6 +117,7 @@ function Get-GeneralDefaults { ShareName = "FFUCaptureShare" Username = "ffu_user" Threads = 5 + BitsPriority = 'Normal' MaxUSBDrives = 5 BuildUSBDriveEnable = $false CompactOS = $true diff --git a/FFUDevelopment/config/Sample_default.json b/FFUDevelopment/config/Sample_default.json index 6b8a335..cf5d7a6 100644 Binary files a/FFUDevelopment/config/Sample_default.json and b/FFUDevelopment/config/Sample_default.json differ