From 6d80b25d346fd55c5f74bf9ad2c91bd56486b42f Mon Sep 17 00:00:00 2001 From: asheroto Date: Tue, 20 Jun 2023 08:01:26 -0500 Subject: [PATCH] Update --- .github/README.md | 2 + .gitignore | 2 + winget-install.ps1 | 221 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 172 insertions(+), 53 deletions(-) create mode 100644 .gitignore diff --git a/.github/README.md b/.github/README.md index 3565f27..85e1db4 100644 --- a/.github/README.md +++ b/.github/README.md @@ -42,6 +42,8 @@ Install-Script winget-install -Force - answer **Yes** to all prompts if asked **Note:** `-Force` is optional, but it will force the script to update if it is outdated. +The script is published on [PowerShell Gallery](https://www.powershellgallery.com/packages/winget-install) under `winget-install`. + ### Tip - How to trust PSGallery If you want to trust PSGallery so you aren't prompted each time you run this command, you can type... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98f42a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +UPDATE-NOTES +dist/ \ No newline at end of file diff --git a/winget-install.ps1 b/winget-install.ps1 index c114740..8c2f252 100644 --- a/winget-install.ps1 +++ b/winget-install.ps1 @@ -1,6 +1,6 @@ <#PSScriptInfo -.VERSION 1.0.1 +.VERSION 1.0.2 .GUID 3b581edb-5d90-4fa1-ba15-4f2377275463 @@ -20,6 +20,7 @@ [Version 0.0.5] - Updated version number of dependencies. [Version 1.0.0] - Major refactor code, see release notes for more information. [Version 1.0.1] - Fixed minor bug where version 2.8 was hardcoded in URL. +[Version 1.0.2] - Hardcoded UI Xaml version 2.8.4 as a failsafe in case the API fails. Improved CheckForUpdates function by converting time to local time and switching to variables. Various bug fixes. #> @@ -31,28 +32,118 @@ .EXAMPLE Install-Winget .NOTES - Version : 1.0.1 + Version : 1.0.2 Created by : asheroto .LINK Project Site: https://github.com/asheroto/winget-installer #> +param ( + [switch]$Version, + [switch]$Help, + [switch]$CheckForUpdates +) + +# Version +$CurrentVersion = '1.0.2' +$RepoOwner = 'asheroto' +$RepoName = 'winget-installer' + # Versions $VCLibsVersion = "14.00" $ProgressPreference = 'SilentlyContinue' # Suppress progress bar (makes downloading super fast) +# Check if -Version is specified +if ($Version.IsPresent) { + $CurrentVersion + exit 0 +} + +# Help +if ($Help) { + Get-Help -Name $MyInvocation.MyCommand.Source -Full + exit 0 +} + +function Check-GitHubRelease { + param ( + [string]$Owner, + [string]$Repo + ) + try { + $url = "https://api.github.com/repos/$Owner/$Repo/releases/latest" + $response = Invoke-RestMethod -Uri $url -ErrorAction Stop + + $latestVersion = $response.tag_name + $publishedAt = $response.published_at + $UtcDateTimeFormat = "MM/dd/yyyy HH:mm:ss" + + # Convert UTC time string to local time + $UtcDateTime = [DateTime]::ParseExact($publishedAt, $UtcDateTimeFormat, $null) + $PublishedLocalDateTime = $UtcDateTime.ToLocalTime() + + [PSCustomObject]@{ + LatestVersion = $latestVersion + PublishedDateTime = $PublishedLocalDateTime + } + } catch { + Write-Error "Unable to check for updates. Error: $_" + exit 1 + } +} + +# Check for updates +if ($CheckForUpdates) { + $Data = Check-GitHubRelease -Owner $RepoOwner -Repo $RepoName + + if ($Data.LatestVersion -gt $CurrentVersion) { + Write-Output "A new version of $RepoName is available.`nCurrent version: $CurrentVersion. Latest version: $($Data.LatestVersion). Published at: $($Data.PublishedDateTime)." + Write-Output "You can download the latest version from https://github.com/$RepoOwner/$RepoName/releases" + } else { + Write-Output "$RepoName is up to date.`nCurrent version: $CurrentVersion. Latest version: $($Data.LatestVersion). Published at: $($Data.PublishedDateTime)." + Write-OUtput "Repository: https://github.com/$RepoOwner/$RepoName/releases" + } + exit 0 +} + # Get latest version of Microsoft.UI.Xaml -function Get-LatestMicrosoftUIXamlVersion() { +function Get-LatestMicrosoftUIXamlVersion { + # Get latest version from API $url = "https://api.nuget.org/v3-flatcontainer/Microsoft.UI.Xaml/index.json" - $json = Invoke-RestMethod -Method Get -Uri $url - # The versions are in reverse chronological order, so the first one is the latest - $latestVersion = $json.versions[-1] + + # Try to get the latest version from the API, if it fails, use the hardcoded version + try { + # Get the JSON from the API + $json = Invoke-RestMethod -Method Get -Uri $url + + # Remove all versions containing "prerelease" + $filteredVersions = $json.versions | Where-Object { $_ -notlike "*-*" } + + # Extract the versions using regular expressions + $versions = $filteredVersions | ForEach-Object { + if ($_ -match '(\d+\.\d+\.\d+)') { + $matches[1] + } + } + + # Sort the versions array in descending order + $sortedVersions = $versions | Sort-Object -Descending + + # Get the latest version + $latestVersion = $sortedVersions[0] + } catch { + # If the API fails, use the hardcoded version + $latestVersion = "2.8.4" + } + return $latestVersion } +## KEEP THIS HERE AFTER Get-LatestMicrosoftUIXamlVersion # Initialize Microsoft.UI.Xaml version $MicrosoftUIXamlVersion = Get-LatestMicrosoftUIXamlVersion +# KEEP THIS HERE AFTER $MicrosoftUIXamlVersion # URLs $urlMicrosoftUIXaml = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/$MicrosoftUIXamlVersion" $urlVCLibsx64 = "https://aka.ms/Microsoft.VCLibs.x64.$VCLibsVersion.Desktop.appx" @@ -88,7 +179,7 @@ function Get-NewestLink($match) { .SYNOPSIS This function fetches the newest link for a specified match from the GitHub API. .EXAMPLE - PS C:\> Get-NewestLink("msixbundle") + Get-NewestLink("msixbundle") #> $uri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest" Write-Verbose "[$((Get-Date).TimeofDay)] Getting information from $uri" @@ -104,51 +195,75 @@ $tempFolder = [System.IO.Path]::GetTempPath() # Determine architecture $arch = if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" } -# Download XAML nupkg and extract appx file -Write-Output "" -Write-Section("Downloading Xaml nupkg file...") -$zipFile = Join-Path -Path $tempFolder -ChildPath "Microsoft.UI.Xaml.$MicrosoftUIXamlVersion.nupkg.zip" -Invoke-WebRequest -Uri $urlMicrosoftUIXaml -OutFile $zipFile -$nupkgFolder = Join-Path -Path $tempFolder -ChildPath "Microsoft.UI.Xaml.$MicrosoftUIXamlVersion" -Expand-Archive -Path $zipFile -DestinationPath $nupkgFolder -Force - -# Install VCLibs -Write-Section("Downloading & installing ${arch} VCLibs...") -$urlVCLibs = if ($arch -eq "x64") { $urlVCLibsx64 } else { $urlVCLibsx86 } -Add-AppxPackageSilently $urlVCLibs - -# Install XAML -Write-Section("Installing ${arch} XAML...") -$XamlAppxPath = Join-Path -Path $nupkgFolder -ChildPath "tools\AppX\$arch\Release\Microsoft.UI.Xaml.$MicrosoftUIXamlVersion.appx" -Add-AppxPackageSilently $XamlAppxPath - -# Finally, install winget -$wingetUrl = Get-NewestLink("msixbundle") -$wingetPath = Join-Path -Path $tempFolder -ChildPath "winget.msixbundle" -$wingetLicenseUrl = Get-NewestLink("License1.xml") -$wingetLicensePath = Join-Path -Path $tempFolder -ChildPath "license1.xml" -Write-Section("Downloading winget...") -Invoke-WebRequest -Uri $wingetUrl -OutFile $wingetPath -Invoke-WebRequest -Uri $wingetLicenseUrl -OutFile $wingetLicensePath -Write-Section("Installing winget...") -Add-AppxProvisionedPackage -Online -PackagePath $wingetPath -LicensePath $wingetLicensePath -ErrorAction SilentlyContinue | Out-Null - -# Adding WindowsApps directory to PATH variable for current user if not already present -Write-Section("Checking and adding WindowsApps directory to PATH variable for current user if not present...") -$path = [Environment]::GetEnvironmentVariable("PATH", "User") -$WindowsAppsPath = [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps") -if (!$path.Contains($WindowsAppsPath)) { - $path = $path + ";" + $WindowsAppsPath - [Environment]::SetEnvironmentVariable("PATH", $path, "User") -} +try { + # Spacer + Write-Output "" + + # Download XAML nupkg and extract appx file + Write-Section("Downloading Xaml nupkg file...") + $zipFile = Join-Path -Path $tempFolder -ChildPath "Microsoft.UI.Xaml.$MicrosoftUIXamlVersion.nupkg.zip" + Write-Output "Downloading $urlMicrosoftUIXaml`nSaving as: $zipFile`n" + try { + Invoke-WebRequest -Uri $urlMicrosoftUIXaml -OutFile $zipFile + } catch { + Write-Warning "Failed to download $urlMicrosoftUIXaml" + Write-Warning "Will try again using hardcoded version 2.8.4 (known good)..." + Write-Output "Downloading:`n$urlMicrosoftUIXaml`nSaving as: $zipFile`n" + $DownloadURL = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.8.4" + Invoke-WebRequest -Uri $DownloadURL -OutFile $zipFile + } + $nupkgFolder = Join-Path -Path $tempFolder -ChildPath "Microsoft.UI.Xaml.$MicrosoftUIXamlVersion" + Write-Output "Expanding: $zipFile`nInto: $nupkgFolder`n" + Expand-Archive -Path $zipFile -DestinationPath $nupkgFolder -Force -# Cleanup -Write-Section("Cleaning up...") -Remove-Item -Path $zipFile -Remove-Item -Path $nupkgFolder -Recurse -Remove-Item -Path $wingetPath -Remove-Item -Path $wingetLicensePath + # Install VCLibs + Write-Section("Downloading & installing ${arch} VCLibs...") + $urlVCLibs = if ($arch -eq "x64") { $urlVCLibsx64 } else { $urlVCLibsx86 } + Add-AppxPackageSilently $urlVCLibs -# Finished -Write-Section("Installation complete!") -Write-Section("Please restart your computer to complete the installation.") \ No newline at end of file + # Install XAML + Write-Section("Installing ${arch} XAML...") + $XamlAppxPath = Join-Path -Path $nupkgFolder -ChildPath "tools\AppX\$arch\Release\Microsoft.UI.Xaml.$MicrosoftUIXamlVersion.appx" + Add-AppxPackageSilently $XamlAppxPath + + # Download winget + Write-Output "Retrieving download URL for winget from GitHub...`n" + $wingetUrl = Get-NewestLink("msixbundle") + $wingetPath = Join-Path -Path $tempFolder -ChildPath "winget.msixbundle" + $wingetLicenseUrl = Get-NewestLink("License1.xml") + $wingetLicensePath = Join-Path -Path $tempFolder -ChildPath "license1.xml" + Write-Section("Downloading winget...") + Write-Output "Downloading:`n$wingetUrl`nSaving as: $wingetPath`n" + Invoke-WebRequest -Uri $wingetUrl -OutFile $wingetPath + Write-Output "Downloading:`n$wingetLicenseUrl`nSaving as: $wingetLicensePath`n" + Invoke-WebRequest -Uri $wingetLicenseUrl -OutFile $wingetLicensePath + + # Install winget + Write-Section("Installing winget...") + Add-AppxProvisionedPackage -Online -PackagePath $wingetPath -LicensePath $wingetLicensePath -ErrorAction SilentlyContinue | Out-Null + + # Adding WindowsApps directory to PATH variable for current user if not already present + Write-Section("Checking and adding WindowsApps directory to PATH variable for current user if not present...") + $path = [Environment]::GetEnvironmentVariable("PATH", "User") + $WindowsAppsPath = [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps") + if (!$path.Contains($WindowsAppsPath)) { + $path = $path + ";" + $WindowsAppsPath + [Environment]::SetEnvironmentVariable("PATH", $path, "User") + } + + # Cleanup + Write-Section("Cleaning up...") + Remove-Item -Path $zipFile + Remove-Item -Path $nupkgFolder -Recurse + Remove-Item -Path $wingetPath + Remove-Item -Path $wingetLicensePath + + # Finished + Write-Section("Installation complete!") + Write-Section("Please restart your computer to complete the installation.") + + # Spacer + Write-Output "" +} catch { + Write-Output "Something went wrong. Please try again or open an issue at https://github.com/asheroto/winget-install/issues" +} \ No newline at end of file