Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix winget for good #3096

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions Test-WingetInstall.ps1
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
# Import the function (adjust the path according to your setup)
. "./functions/private/Get-WinUtilWingetLatest.ps1"
. "./functions/private/Install-WinUtilWinget.ps1"
. "./functions/private/Test-WinUtilPackageManager.ps1"

# Set up Information stream to be visible
$InformationPreference = "Continue"

Write-Host "Starting Winget installation test..." -ForegroundColor Cyan

try {
# Test the function with verbose output
Write-Host "Attempting to run Get-WinUtilWingetLatest..." -ForegroundColor Cyan
Get-WinUtilWingetLatest -Verbose

# Verify Winget is working
if (Get-Command winget -ErrorAction SilentlyContinue) {
Write-Host "Success! Winget is installed and accessible." -ForegroundColor Green

# Display Winget version
Write-Host "`nWinget version:" -ForegroundColor Cyan
winget --version
} else {
Write-Host "Warning: Winget is installed but not accessible in the current session. You may need to restart your terminal." -ForegroundColor Yellow
}
Install-WinUtilWinget
} catch {
Write-Host "Error occurred during testing: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Stack Trace:" -ForegroundColor Red
Expand Down
104 changes: 0 additions & 104 deletions functions/private/Get-WinUtilWingetLatest.ps1

This file was deleted.

120 changes: 110 additions & 10 deletions functions/private/Install-WinUtilWinget.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,118 @@ function Install-WinUtilWinget {
return
}

# Install Winget via GitHub method.
# Used part of my own script with some modification: ruxunderscore/windows-initialization
Write-Host "Downloading Winget and License File`r"
Get-WinUtilWingetLatest
Write-Host "Enabling NuGet and Module..."
Install-PackageProvider -Name NuGet -Force
Install-Module -Name Microsoft.WinGet.Client -Force
# Winget only needs a refresh of the environment variables to be used.
Write-Host "Attempting to install/update Winget`r"
try {
$wingetCmd = Get-Command winget -ErrorAction Stop
Write-Information "Attempting to update WinGet using WinGet..."
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
if ($result.ExitCode -ne 0) {
throw "WinGet update failed with exit code: $($result.ExitCode)"
}
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
return
} catch {
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
}

# 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
} else {
throw "Installation failed with status: $($deploymentOperation.Status)"
}
} 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..."
}
# 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 "Failed to install Winget: $($_.Exception.Message)"
Write-Error "All installation methods failed. Unable to install WinGet."
throw
}

}
Loading