diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 index 0319ffe..d2dc8a4 100644 --- a/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 +++ b/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 @@ -68,8 +68,18 @@ function Get-Application { $architecturesToDownload = if ($WindowsArch -eq 'x86 x64') { @('x86', 'x64') } else { @($WindowsArch) } $overallResult = 0 + # For msstore, we don't specify architecture, so we only need to loop once. + if ($Source -eq 'msstore') { + $architecturesToDownload = @('neutral') # Use a placeholder to loop once + } + foreach ($arch in $architecturesToDownload) { - WriteLog "Processing '$AppName' for architecture '$arch'." + if ($Source -eq 'msstore') { + WriteLog "Processing '$AppName' for all architectures." + } + else { + WriteLog "Processing '$AppName' for architecture '$arch'." + } # Determine app type and folder path $appIsWin32 = ($Source -eq 'msstore' -and $AppId.StartsWith("XP")) @@ -91,22 +101,35 @@ function Get-Application { # Create app folder New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null - # Log download information - WriteLog "Downloading $AppName for $arch architecture..." - if ($Source -eq 'msstore') { - WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.' + # Build download parameters and log information + $downloadParams = @{ + id = $AppId + DownloadDirectory = $appFolderPath + Source = $Source + } + + if ($Source -ne 'msstore') { + $downloadParams.Architecture = $arch + WriteLog "Downloading $AppName for $arch architecture..." + WriteLog "WinGet command: Export-WinGetPackage -id $AppId -DownloadDirectory `"$appFolderPath`" -Architecture $arch -Source $Source" + } + else { + WriteLog "Downloading $AppName for all architectures..." + WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.' + WriteLog "WinGet command: Export-WinGetPackage -id $AppId -DownloadDirectory `"$appFolderPath`" -Source $Source" } - WriteLog "WinGet command: Export-WinGetPackage -id $AppId -DownloadDirectory `"$appFolderPath`" -Architecture $arch -Source $Source" # Download the app - $wingetDownloadResult = Export-WinGetPackage -id $AppId -DownloadDirectory $appFolderPath -Architecture $arch -Source $Source + $wingetDownloadResult = Export-WinGetPackage @downloadParams # Handle download status if ($wingetDownloadResult.status -ne 'Ok') { - # Try downloading without architecture if no applicable installer found - if ($wingetDownloadResult.status -eq 'NoApplicableInstallers' -or $wingetDownloadResult.status -eq 'NoApplicableInstallerFound') { + # For winget source, try downloading without architecture if the specified one fails + if (($Source -eq 'winget') -and ($wingetDownloadResult.status -eq 'NoApplicableInstallers' -or $wingetDownloadResult.status -eq 'NoApplicableInstallerFound')) { WriteLog "No installer found for $arch architecture. Attempting to download without specifying architecture..." - $wingetDownloadResult = Export-WinGetPackage -id $AppId -DownloadDirectory $appFolderPath -Source $Source + # Remove the architecture parameter and try again + $downloadParams.Remove('Architecture') + $wingetDownloadResult = Export-WinGetPackage @downloadParams } # Re-evaluate status after potential second attempt diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 index d97c732..d2f15e9 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 @@ -411,7 +411,7 @@ function Initialize-DynamicUIElements { $comboBoxFactory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.ComboBox]) # The ItemsSource for the ComboBox - $availableArchitectures = @('x86', 'x64', 'arm64', 'x86 x64') + $availableArchitectures = @('x86', 'x64', 'arm64', 'x86 x64', 'NA') $comboBoxFactory.SetValue([System.Windows.Controls.ItemsControl]::ItemsSourceProperty, $availableArchitectures) # Bind the text property to the 'Architecture' property of the data item. @@ -420,6 +420,18 @@ function Initialize-DynamicUIElements { $binding.Mode = [System.Windows.Data.BindingMode]::TwoWay $comboBoxFactory.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $binding) + # Create a style to disable the ComboBox for 'msstore' source + $comboBoxStyle = New-Object System.Windows.Style + $comboBoxStyle.TargetType = [System.Windows.Controls.ComboBox] + + $dataTrigger = New-Object System.Windows.DataTrigger + $dataTrigger.Binding = New-Object System.Windows.Data.Binding("Source") + $dataTrigger.Value = "msstore" + $dataTrigger.Setters.Add((New-Object System.Windows.Setter([System.Windows.Controls.ComboBox]::IsEnabledProperty, $false))) + + $comboBoxStyle.Triggers.Add($dataTrigger) + $comboBoxFactory.SetValue([System.Windows.FrameworkElement]::StyleProperty, $comboBoxStyle) + $archCellTemplate.VisualTree = $comboBoxFactory $archColumn.CellTemplate = $archCellTemplate $wingetGridView.Columns.Add($archColumn) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 index 56b3c9e..84b615e 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 @@ -146,13 +146,14 @@ function Import-WingetList { $defaultArch = $State.Controls.cmbWindowsArch.SelectedItem foreach ($appInfo in $importedAppsData.apps) { + $arch = if ($appInfo.source -eq 'msstore') { 'NA' } else { if ($appInfo.PSObject.Properties['architecture']) { $appInfo.architecture } else { $defaultArch } } $newAppListForItemsSource.Add([PSCustomObject]@{ IsSelected = $true # Imported apps are marked as selected Name = $appInfo.name Id = $appInfo.id Version = "" # Will be populated when searching or if data exists Source = $appInfo.source - Architecture = if ($appInfo.PSObject.Properties['architecture']) { $appInfo.architecture } else { $defaultArch } + Architecture = $arch DownloadStatus = "" }) } @@ -188,13 +189,14 @@ function Search-WingetPackagesPublic { WriteLog "Found $($results.Count) packages matching query '$Query'." WriteLog "Creating output objects for Winget search results, please wait..." $output = $results | ForEach-Object -Parallel { + $arch = if ($_.Source -eq 'msstore') { 'NA' } else { $using:DefaultArchitecture } [PSCustomObject]@{ IsSelected = [bool]$false Name = [string]$_.Name Id = [string]$_.Id Version = [string]$_.Version Source = [string]$_.Source - Architecture = [string]$using:DefaultArchitecture + Architecture = [string]$arch DownloadStatus = [string]::Empty } } -ThrottleLimit 20