Files
Win11Debloat/Scripts/FileIO/Import-AppDetailsFromJson.ps1
T
SashankandGitHub 6feebba878 Add localization for app names and descriptions (#769)
* Translate app names and descriptions in Config/Apps.json

* Document Apps section and first-ID translation key for multi-ID apps

* Fix app list breaking when "Only show installed" runs translation in an isolated runspace
2026-10-01 21:25:34 +02:00

140 lines
5.3 KiB
PowerShell

<#
.SYNOPSIS
Loads application details from Apps.json.
.DESCRIPTION
Reads the application definitions from Apps.json, optionally filters the
results to installed applications, and returns normalized app objects for
display and selection.
.PARAMETER OnlyInstalled
Filters the results to applications detected through Appx or the supplied
winget installation list.
.PARAMETER InstalledList
A pre-fetched winget installation list used when filtering installed apps.
.PARAMETER InitialCheckedFromJson
Sets each returned app's IsChecked value from its SelectedByDefault setting.
.OUTPUTS
System.Management.Automation.PSCustomObject[]
Application detail objects containing display, selection, and removal data.
#>
function Import-AppDetailsFromJson {
param (
[switch]$OnlyInstalled,
[object[]]$InstalledList = $null,
[switch]$InitialCheckedFromJson
)
$apps = @()
try {
$jsonContent = Get-Content -Path $script:AppsListFilePath -Raw | ConvertFrom-Json
}
catch {
Write-Error "Failed to read Apps.json: $_"
return $apps
}
foreach ($appData in $jsonContent.Apps) {
# Handle AppId as array (could be single or multiple IDs)
$appIdArray = @(
foreach ($rawAppId in @($appData.AppId)) {
if ($rawAppId -isnot [string]) { continue }
$normalizedAppId = $rawAppId.Trim()
if ($normalizedAppId.Length -gt 0) { $normalizedAppId }
}
)
if ($appIdArray.Count -eq 0) { continue }
if ($OnlyInstalled) {
$isInstalled = $false
foreach ($appId in $appIdArray) {
# Check Get-AppxPackage first (fast, no process launch)
if (Get-AppxPackage -Name $appId) {
$isInstalled = $true
break
}
# Then check the pre-fetched winget list
if ($InstalledList -and (Test-AppInWingetList -appId $appId -InstalledList $InstalledList)) {
$isInstalled = $true
break
}
}
if (-not $isInstalled) { continue }
}
# Use first AppId for fallback names, join all for display
$primaryAppId = $appIdArray[0]
$appIdDisplay = $appIdArray -join ', '
$friendlyName = Get-Translation -Key $primaryAppId -Field 'FriendlyName' -Section 'Apps'
$displayName = "$friendlyName ($appIdDisplay)"
$isChecked = if ($InitialCheckedFromJson) { $appData.SelectedByDefault } else { $false }
$apps += [PSCustomObject]@{
AppId = $appIdArray
AppIdDisplay = $appIdDisplay
FriendlyName = $friendlyName
DisplayName = $displayName
IsChecked = $isChecked
Description = Get-Translation -Key $primaryAppId -Field 'Description' -Section 'Apps'
SelectedByDefault = $appData.SelectedByDefault
Recommendation = $appData.Recommendation
RemovalMethod = if ($appData.RemovalMethod -and $appData.RemovalMethod -eq 'WinGet') { 'WinGet' } else { 'Appx' }
}
}
return $apps
}
<#
.SYNOPSIS
Runs Import-AppDetailsFromJson in a background runspace via Invoke-NonBlocking.
.DESCRIPTION
The runspace inherits neither dot-sourced functions nor script-scoped variables, so
this dot-sources the app loader, its winget helper, and the language loader inside the
scriptblock, and passes $Lang through to be reassigned to $script:Lang there.
.PARAMETER OnlyInstalled
Filters the results to applications detected through Appx or the supplied
winget installation list.
.PARAMETER InstalledList
A pre-fetched winget installation list used when filtering installed apps.
.PARAMETER InitialCheckedFromJson
Sets each returned app's IsChecked value from its SelectedByDefault setting.
.PARAMETER Lang
The loaded language object ($script:Lang) to make available inside the runspace.
#>
function Invoke-AppDetailsFromJsonAsync {
param (
[string]$LoaderScriptPath = $script:LoadAppsDetailsScriptPath,
[string]$HelperScriptPath = $script:TestAppInWingetListScriptPath,
[string]$LanguageFileScriptPath = $script:ImportLanguageFileScriptPath,
[string]$AppsFilePath = $script:AppsListFilePath,
[object[]]$InstalledList = $null,
[switch]$OnlyInstalled,
[switch]$InitialCheckedFromJson,
[object]$Lang = $script:Lang
)
$onlyInstalledValue = [bool]$OnlyInstalled
$initialCheckedFromJsonValue = [bool]$InitialCheckedFromJson
return Invoke-NonBlocking -ScriptBlock {
param($loaderScript, $helperScript, $languageFileScript, $appsListFilePath, $installedList, $onlyInstalled, $initialCheckedFromJson, $Lang)
$script:AppsListFilePath = $appsListFilePath
$script:Lang = $Lang
. $helperScript
. $languageFileScript
. $loaderScript
Import-AppDetailsFromJson -OnlyInstalled:$onlyInstalled -InstalledList $installedList -InitialCheckedFromJson:$initialCheckedFromJson
} -ArgumentList $LoaderScriptPath, $HelperScriptPath, $LanguageFileScriptPath, $AppsFilePath, $InstalledList, $onlyInstalledValue, $initialCheckedFromJsonValue, $Lang
}