fix(installer): install the Visual C++ runtime before MySQL, and log the MSI
Second failure from the Server 2019 test. The previous fix worked - msiexec went from exit 1639 (ERROR_INVALID_COMMAND_LINE, which is why it printed its usage dialog) to exit 1603 (ERROR_INSTALL_FAILURE), so the command line parses now and the MSI itself is failing. It failed in 1.1 seconds. An MSI that dies that fast has not begun installing; it has failed a launch condition. MySQL 8.4 requires the Visual C++ redistributable and a bare Windows Server does not ship it - the same runtime mysql.exe and mysqldump.exe import, which was visible when their DLL dependencies were trimmed and went unnoticed. Stage 0 now installs VC_redist.x64.exe from the bundle before touching MySQL, skipping it when vcruntime140.dll is already present, and fails with a sentence naming the requirement if the redistributable is absent from the bundle altogether. vcredist\ is an optional locked payload. msiexec also gets /l*v now. A bare 1603 names neither the failing action nor the reason, and it is the most common MySQL install failure - diagnosing this one took a launch-condition inference rather than a log. The MSI log lands beside the installer's own in ProgramData, so the next failure is readable instead of guessed at.
This commit is contained in:
@@ -677,9 +677,42 @@ Skip stage 0 and point the installer at the existing server with -DbHost.
|
||||
Write-Log "could not start msiserver: $($_.Exception.Message)" 'WARN'
|
||||
}
|
||||
}
|
||||
# The Visual C++ runtime, BEFORE MySQL. MySQL's MSI carries a launch
|
||||
# condition requiring it, and a bare Windows Server does not ship it -
|
||||
# so on a fresh box the MSI aborts in about a second with the generic
|
||||
# exit 1603 and no indication of what was missing. That is what a real
|
||||
# Server 2019 install did.
|
||||
$vcMarker = Join-Path $env:windir 'system32\vcruntime140.dll'
|
||||
if (Test-Path $vcMarker) {
|
||||
Write-Log 'Visual C++ runtime already present' 'OK'
|
||||
} else {
|
||||
$vc = Get-ChildItem (Join-Path $BundleRoot 'vcredist') -Filter '*.exe' -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if (-not $vc) {
|
||||
Fail 'the Visual C++ runtime is missing and no redistributable is in the bundle' @'
|
||||
MySQL will not install without it - its MSI fails with a bare exit 1603.
|
||||
Add vcredist\VC_redist.x64.exe to the bundle and rebuild, or install the
|
||||
Microsoft Visual C++ 2015-2022 Redistributable (x64) on this server by hand.
|
||||
'@
|
||||
}
|
||||
Write-Log "installing $($vc.Name) (MySQL requires it)"
|
||||
if (-not $WhatIfOnly) {
|
||||
Invoke-Native $vc.FullName @('/install','/quiet','/norestart') `
|
||||
'Visual C++ runtime' -TimeoutSec 600
|
||||
Write-Log 'Visual C++ runtime installed' 'OK'
|
||||
}
|
||||
}
|
||||
|
||||
# Quiet MSI. INSTALLDIR must have no trailing backslash or the MSI mis-parses it.
|
||||
Write-Log "installing $($msi.Name) (125MB, takes a minute)"
|
||||
# /l*v: without the MSI's own log, exit 1603 says only "something went
|
||||
# wrong" - it names neither the action nor the reason, and it is the most
|
||||
# common MySQL failure code. Costs nothing and turns the next failure
|
||||
# into something readable.
|
||||
$msiLog = Join-Path $script:LogDir ('mysql-msi-{0}.log' -f (Get-Date -Format 'yyyyMMdd-HHmmss'))
|
||||
Write-Log "MSI log: $msiLog"
|
||||
Invoke-Native 'msiexec.exe' @('/i', $msi.FullName, '/quiet', '/norestart',
|
||||
'/l*v', $msiLog,
|
||||
"INSTALLDIR=$MysqlRoot") 'MySQL MSI' -TimeoutSec 900
|
||||
}
|
||||
# An installer exit code of 0 does NOT mean it did what you asked - the Python
|
||||
|
||||
Reference in New Issue
Block a user