Move the PowerShell code from .github/workflow/cmake-builds.yml into its own script, cmake/github_v141_xp.ps1, to keep cmake-buils.yml readable. The script also facilitates synchronizng with the Chocolatey installer's Wait-VSIstallerProcesses function easier (from which this this code is derived.) cmake-builds.yml: Check the output from Get-VSSetupInstance and Set-VSSetupInstance. Empty (or null) output indicates that the v141_xp install did not complete successfully. Build process will bail when that happens. cmake/v141_xp_install.ps1: Unused and now unnecessary script.
153 lines
6.1 KiB
PowerShell
153 lines
6.1 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Install Visual Studio's 'v141_xp' XP toolkit on Github.
|
|
|
|
.DESCRIPTION
|
|
Update the existing Github Visual Studio installation in-place. This script
|
|
will iterate through all VS installations identified by the `vswhere` utility.
|
|
|
|
This script is Grey Magic. The `vs_installer` installer utility exits almost
|
|
immediately if you run it from the command line. `vs_installer`'s subprocesses
|
|
are reasonably well known, which allows this script to query the processes and
|
|
wait for them to terminate.
|
|
|
|
GitHub Actions does something strange with stdout and stderr, so you won't get any
|
|
indication of failure or output that shows you that something is happening.
|
|
|
|
The waiting code was adapted from the Chocolatey VS installer scripts (Wait-VSIstallerProcesses).
|
|
|
|
Ref: https://github.com/jberezanski/ChocolateyPackages/blob/master/chocolatey-visualstudio.extension/extensions/Wait-VSInstallerProcesses.ps1
|
|
#>
|
|
|
|
$exitcode = $null
|
|
$vswhere = "${env:ProgramFiles} (x86)\Microsoft Visual Studio\Installer\vswhere"
|
|
$vsinstaller = "${env:ProgramFiles} (x86)\Microsoft Visual Studio\Installer\vs_installer.exe"
|
|
$vsInstallOut = "$env:TEMP\vsinstall-out.txt"
|
|
$vsInstallErr = "$env:TEMP\vsinstall-err.txt"
|
|
|
|
& ${vswhere} -property installationPath | Foreach-Object -process {
|
|
# Save the installlation path for the current iteration
|
|
$installPath = $_
|
|
|
|
# Make sure that previously running installers have all exited.
|
|
Write-Debug ('Looking for previously running VS installer processes')
|
|
$lazyQuitterProcessNames = @('vs_installershell', 'vs_installerservice')
|
|
do
|
|
{
|
|
$lazyQuitterProcesses = Get-Process -Name $lazyQuitterProcessNames -ErrorAction SilentlyContinue | `
|
|
Where-Object { $null -ne $_ -and -not $_.HasExited }
|
|
$lazyQuitterProcessCount = ($lazyQuitterProcesses | Measure-Object).Count
|
|
if ($lazyQuitterProcessCount -gt 0)
|
|
{
|
|
try
|
|
{
|
|
$lazyQuitterProcesses | Sort-Object -Property Name, Id | ForEach-Object { '[{0}] {1}' -f $_.Id, $_.Name } | Write-Debug
|
|
$lazyQuitterProcesses | Wait-Process -Timeout 10 -ErrorAction SilentlyContinue
|
|
}
|
|
finally
|
|
{
|
|
$lazyQuitterProcesses | ForEach-Object { $_.Dispose() }
|
|
$lazyQuitterProcesses = $null
|
|
}
|
|
}
|
|
}
|
|
while ($lazyQuitterProcessCount -gt 0)
|
|
|
|
## Now kick off our install:
|
|
##
|
|
## --quiet: Don't open/show UI
|
|
## --force: Terminate any VS instances forcibly
|
|
## --norestart: Delay reboot after install, if needed
|
|
## --installWhileDownloading: Self-explanitory.
|
|
##
|
|
## Note: "--wait" doesn't.
|
|
$vsinstallParams = @(
|
|
"modify",
|
|
"--installPath", "$installPath",
|
|
"--add", "Microsoft.VisualStudio.Component.VC.v141.x86.x64",
|
|
"--add", "Microsoft.VisualStudio.Component.WinXP",
|
|
"--quiet", "--force", "--norestart", "--installWhileDownloading"
|
|
)
|
|
|
|
& $vsInstaller $vsinstallParams 2> $vsInstallErr > $vsInstallOut
|
|
|
|
## VS installer processes for which we want to wait because installation isn't complete. Yet.
|
|
$vsinstallerProcesses = @( 'vs_bootstrapper', 'vs_setup_bootstrapper', 'vs_installer', 'vs_installershell', `
|
|
'vs_installerservice', 'setup')
|
|
$vsInstallerProcessFilter = { $_.Name -ne 'setup' -or $_.Path -like '*\Microsoft Visual Studio\Installer*\setup.exe' }
|
|
do
|
|
{
|
|
Write-Debug ('Looking for running VS installer processes')
|
|
$vsInstallerRemaining = Get-Process -Name $vsinstallerProcesses -ErrorAction SilentlyContinue | `
|
|
Where-Object { $null -ne $_ -and -not $_.HasExited } | `
|
|
Where-Object $vsInstallerProcessFilter
|
|
$vsInstallerProcessCount = ($vsInstallerRemaining | Measure-Object).Count
|
|
if ($vsInstallerProcessCount -gt 0)
|
|
{
|
|
try
|
|
{
|
|
Write-Debug "Found $vsInstallerProcessCount running Visual Studio installer processes:"
|
|
$vsInstallerRemaining | Sort-Object -Property Name, Id | ForEach-Object { '[{0}] {1}' -f $_.Id, $_.Name } | Write-Debug
|
|
|
|
foreach ($p in $vsInstallerProcesses)
|
|
{
|
|
[void] $p.Handle # make sure we get the exit code http://stackoverflow.com/a/23797762/266876
|
|
}
|
|
|
|
Write-Debug ('Waiting 60 seconds for process(es) to exit...')
|
|
$vsInstallerRemaining | Wait-Process -Timeout 60 -ErrorAction SilentlyContinue
|
|
|
|
foreach ($proc in $vsInstallerProcesses)
|
|
{
|
|
if (-not $proc.HasExited)
|
|
{
|
|
continue
|
|
}
|
|
if ($null -eq $exitCode)
|
|
{
|
|
$exitCode = $proc.ExitCode
|
|
}
|
|
if ($proc.ExitCode -ne 0 -and $null -ne $proc.ExitCode)
|
|
{
|
|
Write-Debug "$($proc.Name) process $($proc.Id) exited with code $($proc.ExitCode)"
|
|
if ($exitCode -eq 0)
|
|
{
|
|
$exitCode = $proc.ExitCode
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
$vsInstallerRemaining | ForEach-Object { $_.Dispose() }
|
|
$vsInstallerRemaining = $null
|
|
}
|
|
}
|
|
}
|
|
while (($vsInstallerStartup -and $vsInstallerStartCount -gt 0) -or $vsInstallerProcessCount -gt 0)
|
|
}
|
|
|
|
if ((Test-Path $vsInstallOut -PathType Leaf) -and (Get-Item $vsInstallOut).length -gt 0kb)
|
|
{
|
|
Write-Output "-- vsinstaller output:"
|
|
Get-Content $vsInstallOut
|
|
}
|
|
else
|
|
{
|
|
Write-Debug "-- No vsinstaller output."
|
|
}
|
|
|
|
if ((Test-Path $vsInstallErr -PathType Leaf) -and (Get-Item $vsInstallErr).length -gt 0kb)
|
|
{
|
|
Write-Output "-- vsinstaller error output:"
|
|
Get-Content $vsInstallErr
|
|
}
|
|
else
|
|
{
|
|
Write-Debug "-- No vsinstaller error/diag output."
|
|
}
|
|
|
|
if ($null -ne $exitcode -and $exitcode -ne 0)
|
|
{
|
|
throw "VS installer exited with non-zero exit status: $exitcode"
|
|
}
|