Private/Get-Win32ToolkitInstallerExtension.ps1
|
function Get-Win32ToolkitInstallerExtension { <# .SYNOPSIS The single source of truth for which installer file extensions the toolkit accepts. .DESCRIPTION These lists used to be duplicated across ~7 sites (download, cache probe, baseline download, file detection, rename), which is how .msixbundle support drifted: one site rejected bundles while another silently accepted a bundle that winget had named '.msix'. APPX-FAMILY NOTE — bundles are ordinary members of this family, not a special case: .msix/.appx and .msixbundle/.appxbundle install through exactly the same cmdlets (Add-AppxProvisionedPackage / Add-AppxPackage accept a bundle path natively) and uninstall by the same package Name. So Get-InstallerFileInfo deliberately reports Type 'msix'/'appx' for a bundle too: Type describes the INSTALL SEMANTICS, and every '-in @(''msix'',''appx'')' check downstream stays correct. Bundle-ness matters in exactly one place — reading the package identity — and Get-Win32ToolkitMsixIdentity detects that from the file's CONTENT, never its extension (winget names PowerShell's .msixbundle '.msix' because the manifest says InstallerType: msix — trusting the extension is what broke identity extraction). .PARAMETER PackagesOnly Return only the Appx-family extensions (no .exe/.msi). .PARAMETER BundlesOnly Return only the bundle extensions. .OUTPUTS [string[]] extensions, dot-prefixed and lower-case (e.g. '.msix'). #> [CmdletBinding()] [OutputType([string[]])] param( [switch]$PackagesOnly, [switch]$BundlesOnly ) $bundles = @('.msixbundle', '.appxbundle') $packages = @('.msix', '.appx') + $bundles # Leading comma: hand back the array as one object so callers get a string[] intact. if ($BundlesOnly) { return , $bundles } if ($PackagesOnly) { return , $packages } return , (@('.exe', '.msi') + $packages) } function Get-Win32ToolkitInstallerType { <# .SYNOPSIS Maps an installer file extension to its INSTALL-SEMANTICS type — the single owner of that mapping. .DESCRIPTION The toolkit's installer Type is 'exe' | 'msi' | 'msix' | 'appx'. Bundles collapse into their family ('.msixbundle' -> 'msix', '.appxbundle' -> 'appx') because they install and uninstall identically; bundle-ness only matters to Get-Win32ToolkitMsixIdentity, which content-detects it. This exists because there were TWO independent extension->Type derivations: Get-InstallerFileInfo (which normalized) and Download-OldVersionInstaller (which returned the RAW extension). Once bundles became acceptable inputs, the un-normalized one started emitting Type 'msixbundle', which silently fell through the guest script's `-eq 'msix' -or -eq 'appx'` dependency dispatch into `Start-Process <file>.msixbundle` — opening the App Installer GUI and hanging the sandbox — and hard-failed Get-Win32ToolkitBaselineInstallCommand's ValidateSet. Both derivations now call this, so the mapping cannot drift again. .PARAMETER Extension File extension, with or without the leading dot (case-insensitive). .OUTPUTS [string] 'exe' | 'msi' | 'msix' | 'appx', or the lower-cased extension when unrecognized. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [AllowEmptyString()] [string]$Extension ) $e = $Extension.TrimStart('.').ToLowerInvariant() switch ($e) { 'msixbundle' { return 'msix' } 'appxbundle' { return 'appx' } default { return $e } } } |