From 3ce3915ddbc855027e1442373bb0a2d48bce3ba6 Mon Sep 17 00:00:00 2001 From: Chris Titus Tech Date: Tue, 4 Mar 2025 14:21:54 -0600 Subject: [PATCH] Removing Github and Nuget method. Revamp of Version check to use DesktopAppInstaller --- functions/private/Install-WinUtilWinget.ps1 | 100 +++--------------- .../private/Test-WinUtilPackageManager.ps1 | 21 ++-- 2 files changed, 28 insertions(+), 93 deletions(-) diff --git a/functions/private/Install-WinUtilWinget.ps1 b/functions/private/Install-WinUtilWinget.ps1 index f7335c86..09c4f017 100644 --- a/functions/private/Install-WinUtilWinget.ps1 +++ b/functions/private/Install-WinUtilWinget.ps1 @@ -48,103 +48,29 @@ function Install-WinUtilWinget { Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..." } try { - # Try to close any running WinGet processes - Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object { - Write-Information "Stopping running WinGet process..." - $_.Kill() - Start-Sleep -Seconds 2 - } + Write-Host "Attempting to repair WinGet using Repair-WinGetPackageManager..." -ForegroundColor Yellow - # Try to load Windows Runtime assemblies more reliably - $null = [System.Runtime.WindowsRuntime.WindowsRuntimeSystemExtensions] - Add-Type -AssemblyName System.Runtime.WindowsRuntime - - # Load required assemblies from Windows SDK - $null = @( - [Windows.Management.Deployment.PackageManager, Windows.Management.Deployment, ContentType = WindowsRuntime] - [Windows.Foundation.Uri, Windows.Foundation, ContentType = WindowsRuntime] - [Windows.Management.Deployment.DeploymentOptions, Windows.Management.Deployment, ContentType = WindowsRuntime] - ) - - # Initialize PackageManager - $packageManager = New-Object Windows.Management.Deployment.PackageManager - - # Rest of the Microsoft Store installation logic - $appxPackage = "https://aka.ms/getwinget" - $uri = New-Object Windows.Foundation.Uri($appxPackage) - $deploymentOperation = $packageManager.AddPackageAsync($uri, $null, "Add") - - # Add timeout check for deployment operation - $timeout = 300 - $timer = [System.Diagnostics.Stopwatch]::StartNew() - - while ($deploymentOperation.Status -eq 0) { - if ($timer.Elapsed.TotalSeconds -gt $timeout) { - throw "Installation timed out after $timeout seconds" - } - Start-Sleep -Milliseconds 100 - } - - if ($deploymentOperation.Status -eq 1) { - Write-Information "Successfully installed WinGet from Microsoft Store" - Write-Output "Refreshing Environment Variables...`n" - $ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") - return + # Check if Windows version supports Repair-WinGetPackageManager (24H2 and above) + if ([System.Environment]::OSVersion.Version.Build -ge 26100) { + Repair-WinGetPackageManager -Force -Latest -Verbose + # Verify if repair was successful + $wingetCmd = Get-Command winget -ErrorAction Stop + Write-Host "WinGet repair successful!" -ForegroundColor Green } else { - throw "Installation failed with status: $($deploymentOperation.Status)" + Write-Host "Repair-WinGetPackageManager is only available on Windows 24H2 and above. Your version doesn't support this method." -ForegroundColor Yellow + throw "Windows version not supported for repair method" } - } catch { - Write-Information "Microsoft Store installation failed. Attempting to install from Nuget..." - } - try { - ## Nuget Method - Write-Host "Enabling NuGet and Module..." - # Enable TLS 1.2 for the PowerShell session - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - # Try to register the NuGet package source if not present - if (-not (Get-PackageSource -Name "NuGet" -ErrorAction SilentlyContinue)) { - Register-PackageSource -Name "NuGet" -Location "https://www.nuget.org/api/v2" -ProviderName NuGet -Force - } - - # Install NuGet provider with error handling - try { - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$false -ErrorAction Stop - } catch { - Write-Warning "Failed to install NuGet provider through standard method. Trying alternative approach..." - Install-PackageProvider -Name NuGet -Source "https://www.powershellgallery.com/api/v2" -Force -Confirm:$false - } - Install-Module -Name Microsoft.WinGet.Client -Confirm:$false -Force - - # Check if WinGet was installed successfully through NuGet - $wingetCmd = Get-Command winget -ErrorAction Stop - Write-Information "Successfully installed WinGet through NuGet" Write-Output "Refreshing Environment Variables...`n" $ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") return + } catch { - Write-Warning "NuGet installation failed. Attempting to install from GitHub..." + Write-Error "All installation methods failed. Unable to install WinGet." + throw } - # GitHub fallback installation method - $releases_url = "https://api.github.com/repos/microsoft/winget-cli/releases/latest" - $asset = (Invoke-RestMethod -Uri $releases_url).assets | - Where-Object { $_.name -match "\.msixbundle$" } | - Select-Object -First 1 - - $download_url = $asset.browser_download_url - $output_path = Join-Path $env:TEMP $asset.name - - Invoke-WebRequest -Uri $download_url -OutFile $output_path - Add-AppxPackage -Path $output_path -ErrorAction Stop - - # Verify installation - $wingetCmd = Get-Command winget -ErrorAction Stop - Write-Information "Successfully installed WinGet through GitHub" - Write-Output "Refreshing Environment Variables...`n" - $ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") - return } catch { - Write-Error "All installation methods failed. Unable to install WinGet." + Write-Error "An error occurred during WinGet installation: $_" throw } } diff --git a/functions/private/Test-WinUtilPackageManager.ps1 b/functions/private/Test-WinUtilPackageManager.ps1 index 04feb83c..b2d7c944 100644 --- a/functions/private/Test-WinUtilPackageManager.ps1 +++ b/functions/private/Test-WinUtilPackageManager.ps1 @@ -23,14 +23,22 @@ function Test-WinUtilPackageManager { # Check if Winget is available while getting it's Version if it's available $wingetExists = $true try { - $wingetVersionFull = winget --version + $wingetInfo = winget --info + # Extract the package version from the output + $wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Microsoft\.DesktopAppInstaller v\d+\.\d+\.\d+\.\d+').Matches.Value + if ($wingetVersionFull) { + $wingetVersionFull = $wingetVersionFull.Split(' ')[-1].TrimStart('v') + } else { + # Fallback in case the pattern isn't found + $wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Package Manager v\d+\.\d+\.\d+').Matches.Value.Split(' ')[-1] + } } catch [System.Management.Automation.CommandNotFoundException], [System.Management.Automation.ApplicationFailedException] { Write-Warning "Winget was not found due to un-availablity reasons" $wingetExists = $false } catch { Write-Warning "Winget was not found due to un-known reasons, The Stack Trace is:`n$($psitem.Exception.StackTrace)" $wingetExists = $false - } + } # If Winget is available, Parse it's Version and give proper information to Terminal Output. # If it isn't available, the return of this funtion will be "not-installed", indicating that @@ -48,13 +56,14 @@ function Test-WinUtilPackageManager { # Check if Winget's Version is too old. $wingetCurrentVersion = [System.Version]::Parse($wingetVersion.Trim('v')) # Grabs the latest release of Winget from the Github API for version check process. - $response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop - $wingetLatestVersion = [System.Version]::Parse(($response.tag_name).Trim('v')) #Stores version number of latest release. - $wingetOutdated = $wingetCurrentVersion -lt $wingetLatestVersion + $response = winget search -e Microsoft.AppInstaller + $wingetLatestVersion = ($response | Select-String -Pattern '\d+\.\d+\.\d+\.\d+').Matches.Value + Write-Host "Latest Search Version: $wingetLatestVersion" -ForegroundColor White + Write-Host "Current Installed Version: $wingetCurrentVersion" -ForegroundColor White + $wingetOutdated = $wingetCurrentVersion -lt [System.Version]::Parse($wingetLatestVersion) Write-Host "===========================================" -ForegroundColor Green Write-Host "--- Winget is installed ---" -ForegroundColor Green Write-Host "===========================================" -ForegroundColor Green - Write-Host "Version: $wingetVersionFull" -ForegroundColor White if (!$wingetPreview) { Write-Host " - Winget is a release version." -ForegroundColor Green