Improve architecture handling for msstore applications

Refactors the application download logic to correctly handle packages from the 'msstore' source, which does not support architecture specification.

- The download process no longer passes an architecture parameter for msstore apps.
- The architecture selection dropdown in the UI is now disabled for msstore apps to prevent invalid configurations.
- Imported or searched msstore apps will display 'NA' for their architecture.
This commit is contained in:
rbalsleyMSFT
2025-07-25 15:29:25 -07:00
parent fc79251f66
commit c57e7ebdfe
3 changed files with 50 additions and 13 deletions
@@ -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) {
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"
}
# 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
@@ -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)
@@ -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