Skip to content

Commit 5bb13e3

Browse files
win: fix store revert for multiple installs #260
This commit improves the revert script for store apps to handle scenarios where `Get-AppxPackage` returns multiple packages. Instead of relying on a single package result, the script now iterates over all found packages and attempts installation using the `AppxManifest.xml` for each. This ensures that even if multiple versions or instances of a package are found, the script will robustly handle and attempt to install each one until successful. Other changes: - Add better message with suggestion if the revert code fails, as discussed in #270. - Improve robustness of finding manifest path by using `Join-Path` instead of basic string concatenation. This resolves wrong paths being built due to missing `\` in file path. - Add check for null or empty `InstallLocation` before accessing manifest path. It prevents errors when accessing `AppxManifest.xml`, enhancing script robustness and reliability. - Improve error handling in manifest file existence check with try-catch block to catch and log exceptions, ensuring uninterrupted script execution in edge cases such as when the script lacks access to read the directory. - Add verification of package installation before attempting to install the package for increased robustness. - Add documentation for revertCode.
1 parent 0466b86 commit 5bb13e3

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

src/application/collections/windows.yaml

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10247,47 +10247,78 @@ functions:
1024710247
codeComment: Uninstall '{{ $packageName }}' Microsoft Store app.
1024810248
code: Get-AppxPackage '{{ $packageName }}' | Remove-AppxPackage
1024910249
# This script attempts to reinstall the app that was just uninstalled, if necessary.
10250-
# The app's package family name is constructed using its name and publisher ID.
10251-
# Package Family Name is: `<name>_<publisherid>`
10252-
# Learn more about package identity: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/package-identity-overview#publisher-id (https://archive.ph/Sx4JC)
10250+
# Re-installation strategy:
10251+
# 1. Attempt to locate the package from another user's installation:
10252+
# - Utilizes the `Get-AppxPackage` command with the `-AllUsers` flag to search across all user installations.
10253+
# - Iterates through the results to locate the manifest file required for re-installation.
10254+
# 2. Attempt to locate the package from the system installation:
10255+
# - Utilizes the `Get-AppxPackage` command with `-RegisterByFamilyName` to search for the manifest file in the system installation.
10256+
# - The app's package family name is constructed using its name and publisher ID.
10257+
# Package Family Name is: `<name>_<publisherid>`
10258+
# Learn more about package identity: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/package-identity-overview#publisher-id (https://archive.ph/Sx4JC)
10259+
# - Based on tests, Windows attempts to locate the file in the installation location of the package.
10260+
# This location can be identified using commands such as `(Get-AppxPackage -AllUsers 'Windows.PrintDialog').InstallLocation`.
10261+
# Possible installation locations include:
10262+
# - `%WINDIR%\SystemApps\{PackageFamilyName}` (for system apps)
10263+
# - `%WINDIR%\{ShortAppName}` (for system apps)
10264+
# - `%SYSTEMDRIVE%\Program Files\WindowsApps\{PackageName}` (for non-system apps)
10265+
# View all package locations: `Get-AppxPackage | Sort Name | Format-Table Name, InstallLocation`
1025310266
revertCodeComment: Reinstall '{{ $packageName }}' if it was previously uninstalled.
1025410267
revertCode: |-
1025510268
$packageName='{{ $packageName }}'
1025610269
$publisherId='{{ $publisherId }}'
10270+
if (Get-AppxPackage -Name $packageName) {
10271+
Write-Host "Skipping, `"$packageName`" is already installed for the current user."
10272+
exit 0
10273+
}
1025710274
Write-Host "Starting the installation process for `"$packageName`"..."
10258-
# Attempting installation using the manifest file
10275+
# Attempt installation using the manifest file
1025910276
Write-Host "Checking if `"$packageName`" is installed on another user profile..."
10260-
$package = Get-AppxPackage -AllUsers $packageName
10261-
if (!$package) {
10277+
$packages = @(Get-AppxPackage -AllUsers $packageName)
10278+
if (!$packages) {
1026210279
Write-Host "`"$packageName`" is not installed on any other user profiles."
1026310280
} else {
10264-
Write-Host "Found package `"$($package.PackageFullName)`"."
10265-
$manifestPath = "$($package.InstallLocation)AppxManifest.xml"
10266-
if (Test-Path "$manifestPath") {
10267-
Write-Host "Manifest file located. Trying to install using the manifest..."
10281+
foreach ($package in $packages) {
10282+
Write-Host "Found package `"$($package.PackageFullName)`"."
10283+
$installationDir = $package.InstallLocation
10284+
if ([string]::IsNullOrWhiteSpace($installationDir)) {
10285+
Write-Warning "Installation directory for `"$packageName`" is not found or invalid."
10286+
continue
10287+
}
10288+
$manifestPath = Join-Path -Path $installationDir -ChildPath 'AppxManifest.xml'
10289+
try {
10290+
if (-Not (Test-Path "$manifestPath")) {
10291+
Write-Host "Manifest file not found for `"$packageName`" on another user profile: `"$manifestPath`"."
10292+
continue
10293+
}
10294+
} catch {
10295+
Write-Warning "An error occurred while checking for the manifest file: $($_.Exception.Message)"
10296+
continue
10297+
}
10298+
Write-Host "Manifest file located. Trying to install using the manifest: `"$manifestPath`"..."
1026810299
try {
1026910300
Add-AppxPackage -DisableDevelopmentMode -Register "$manifestPath" -ErrorAction Stop
1027010301
Write-Host "Successfully installed `"$packageName`" using its manifest file."
1027110302
exit 0
1027210303
} catch {
1027310304
Write-Warning "Error installing from manifest: $($_.Exception.Message)"
1027410305
}
10275-
} else {
10276-
Write-Host "Manifest file not found for `"$packageName`"."
1027710306
}
1027810307
}
10279-
# Attempting installation using the package family name
10308+
# Attempt installation using the package family name
1028010309
$packageFamilyName = "$($packageName)_$($publisherId)"
10281-
Write-Host "Trying to install `"$packageName`" using its package family name: `"$packageFamilyName`"..."
10310+
Write-Host "Trying to install `"$packageName`" using its package family name: `"$packageFamilyName`" from system installation..."
1028210311
try {
1028310312
Add-AppxPackage -RegisterByFamilyName -MainPackage $packageFamilyName -ErrorAction Stop
1028410313
Write-Host "Successfully installed `"$packageName`" using its package family name."
1028510314
exit 0
1028610315
} catch {
1028710316
Write-Warning "Error installing using package family name: $($_.Exception.Message)"
1028810317
}
10289-
# If all methods fail
10290-
throw "Unable to install `"$packageName`". Please check the provided details and try again."
10318+
throw "Unable to reinstall the requested package ($packageName). " + `
10319+
"It appears to no longer be included in this version of Windows. " + `
10320+
"You may search for it or an alternative in the Microsoft Store or " + `
10321+
"consider using an earlier version of Windows where this package was originally provided."
1029110322
-
1029210323
function: RunInlineCode
1029310324
# This script prevents specified applications from being automatically reinstalled during Windows updates.

0 commit comments

Comments
 (0)