Skip to content

Commit

Permalink
Change install to winget, nuget, msstore (#3088)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisTitusTech authored Dec 6, 2024
1 parent 0779dd9 commit d6c1fbe
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 993 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/issue-slash-commands.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
else
echo "label_command=false" >> $GITHUB_ENV
fi
- name: Check for /unlabel command
id: check_unlabel_command
run: |
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
else
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
fi
- name: Reopen issue
if: env.reopen_command == 'true'
env:
Expand All @@ -104,12 +104,12 @@ jobs:
run: |
echo Labeling the issue...
gh issue edit $ISSUE_NUMBER --repo ${{ github.repository }} --add-label "${{ env.label_name }}"
- name: Remove labels
if: env.unlabel_command == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
echo Unlabeling the issue...
gh issue edit $ISSUE_NUMBER --repo ${{ github.repository }} --remove-label "${{ env.unlabel_name }}"
gh issue edit $ISSUE_NUMBER --repo ${{ github.repository }} --remove-label "${{ env.unlabel_name }}"
28 changes: 28 additions & 0 deletions Test-WingetInstall.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Import the function (adjust the path according to your setup)
. "./functions/private/Get-WinUtilWingetLatest.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
}
} catch {
Write-Host "Error occurred during testing: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Stack Trace:" -ForegroundColor Red
$_.ScriptStackTrace
}
112 changes: 95 additions & 17 deletions functions/private/Get-WinUtilWingetLatest.ps1
Original file line number Diff line number Diff line change
@@ -1,26 +1,104 @@
function Get-WinUtilWingetLatest {
[CmdletBinding()]
param()

<#
.SYNOPSIS
Uses GitHub API to check for the latest release of Winget.
.DESCRIPTION
This function grabs the latest version of Winget and returns the download path to Install-WinUtilWinget for installation.
This function first attempts to update WinGet using winget itself, then falls back to manual installation if needed.
#>
# Invoke-WebRequest is notoriously slow when the byte progress is displayed. The following lines disable the progress bar and reset them at the end of the function
$PreviousProgressPreference = $ProgressPreference
$ProgressPreference = "silentlyContinue"
$ProgressPreference = "SilentlyContinue"
$InformationPreference = 'Continue'

try {
# Grabs the latest release of Winget from the Github API for the install process.
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop
$latestVersion = $response.tag_name #Stores version number of latest release.
$licenseWingetUrl = $response.assets.browser_download_url | Where-Object {$_ -like "*License1.xml"} #Index value for License file.
Write-Host "Latest Version:`t$($latestVersion)`n"
Write-Host "Downloading..."
$assetUrl = $response.assets.browser_download_url | Where-Object {$_ -like "*Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"}
Invoke-WebRequest -Uri $licenseWingetUrl -OutFile $ENV:TEMP\License1.xml
# The only pain is that the msixbundle for winget-cli is 246MB. In some situations this can take a bit, with slower connections.
Invoke-WebRequest -Uri $assetUrl -OutFile $ENV:TEMP\Microsoft.DesktopAppInstaller.msixbundle
} catch {
throw [WingetFailedInstall]::new('Failed to get latest Winget release and license')
$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)"
}
return $true
}
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"
return $true
} else {
throw "Installation failed with status: $($deploymentOperation.Status)"
}
}
catch [System.Management.Automation.RuntimeException] {
Write-Information "Windows Runtime components not available. Attempting manual download..."
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
}

# Fallback to direct download from GitHub
$apiUrl = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
$release = Invoke-RestMethod -Uri $apiUrl
$msixBundleUrl = ($release.assets | Where-Object { $_.name -like "*.msixbundle" }).browser_download_url

$tempFile = Join-Path $env:TEMP "Microsoft.DesktopAppInstaller.msixbundle"
Invoke-WebRequest -Uri $msixBundleUrl -OutFile $tempFile

Add-AppxPackage -Path $tempFile -ErrorAction Stop
Remove-Item $tempFile -Force

Write-Information "Successfully installed WinGet from GitHub release"
return $true
}
catch {
Write-Error "Failed to install WinGet: $_"
return $false
}
}
catch {
Write-Error "Failed to install WinGet: $_"
return $false
}
}
$ProgressPreference = $PreviousProgressPreference
}
28 changes: 0 additions & 28 deletions functions/private/Get-WinUtilWingetPrerequisites.ps1

This file was deleted.

20 changes: 1 addition & 19 deletions functions/private/Install-WinUtilWinget.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,16 @@ function Install-WinUtilWinget {

# Install Winget via GitHub method.
# Used part of my own script with some modification: ruxunderscore/windows-initialization
Write-Host "Downloading Winget Prerequsites`n"
Get-WinUtilWingetPrerequisites
Write-Host "Downloading Winget and License File`r"
Get-WinUtilWingetLatest
Write-Host "Installing Winget w/ Prerequsites`r"
Add-AppxProvisionedPackage -Online -PackagePath $ENV:TEMP\Microsoft.DesktopAppInstaller.msixbundle -DependencyPackagePath $ENV:TEMP\Microsoft.VCLibs.x64.Desktop.appx, $ENV:TEMP\Microsoft.UI.Xaml.x64.appx -LicensePath $ENV:TEMP\License1.xml
Write-Host "Manually adding Winget Sources, from Winget CDN."
Add-AppxPackage -Path https://cdn.winget.microsoft.com/cache/source.msix #Seems some installs of Winget don't add the repo source, this should makes sure that it's installed every time.
Write-Host "Winget Installed" -ForegroundColor Green
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-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
} catch {
Write-Host "Failure detected while installing via GitHub method. Continuing with Chocolatey method as fallback." -ForegroundColor Red
# In case install fails via GitHub method.
try {
# Install Choco if not already present
Install-WinUtilChoco
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install winget-cli"
Write-Host "Winget Installed" -ForegroundColor Green
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
} catch {
throw [WingetFailedInstall]::new('Failed to install!')
}
Write-Error "Failed to install Winget: $($_.Exception.Message)"
}

}
Loading

0 comments on commit d6c1fbe

Please sign in to comment.