mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2024-12-22 05:51:30 -06:00
151 lines
7.3 KiB
PowerShell
151 lines
7.3 KiB
PowerShell
function Install-WinUtilWinget {
|
|
<#
|
|
|
|
.SYNOPSIS
|
|
Installs Winget if it is not already installed.
|
|
|
|
.DESCRIPTION
|
|
This function will download the latest version of Winget and install it. If Winget is already installed, it will do nothing.
|
|
#>
|
|
$isWingetInstalled = Test-WinUtilPackageManager -winget
|
|
|
|
try {
|
|
if ($isWingetInstalled -eq "installed") {
|
|
Write-Host "`nWinget is already installed.`r" -ForegroundColor Green
|
|
return
|
|
} elseif ($isWingetInstalled -eq "outdated") {
|
|
Write-Host "`nWinget is Outdated. Continuing with install.`r" -ForegroundColor Yellow
|
|
} else {
|
|
Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red
|
|
}
|
|
|
|
|
|
# Gets the computer's information
|
|
if ($null -eq $sync.ComputerInfo) {
|
|
$ComputerInfo = Get-ComputerInfo -ErrorAction Stop
|
|
} else {
|
|
$ComputerInfo = $sync.ComputerInfo
|
|
}
|
|
|
|
if (($ComputerInfo.WindowsVersion) -lt "1809") {
|
|
# Checks if Windows Version is too old for Winget
|
|
Write-Host "Winget is not supported on this version of Windows (Pre-1809)" -ForegroundColor Red
|
|
return
|
|
}
|
|
|
|
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 "All installation methods failed. Unable to install WinGet."
|
|
throw
|
|
}
|
|
}
|