158 lines
5.6 KiB
PowerShell
158 lines
5.6 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$Installer
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
Add-Type -AssemblyName System.Drawing
|
|
$ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|
|
|
function Get-AssociatedIconHash {
|
|
param([Parameter(Mandatory = $true)][string]$FilePath)
|
|
|
|
$Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($FilePath)
|
|
if (-not $Icon) {
|
|
throw "Unable to extract the Windows icon from: $FilePath"
|
|
}
|
|
$Bitmap = New-Object System.Drawing.Bitmap 32, 32
|
|
$Graphics = [System.Drawing.Graphics]::FromImage($Bitmap)
|
|
$Stream = New-Object System.IO.MemoryStream
|
|
$Hasher = [System.Security.Cryptography.SHA256]::Create()
|
|
try {
|
|
$Graphics.Clear([System.Drawing.Color]::Transparent)
|
|
$Graphics.DrawIcon($Icon, 0, 0)
|
|
$Bitmap.Save($Stream, [System.Drawing.Imaging.ImageFormat]::Png)
|
|
$Hash = $Hasher.ComputeHash($Stream.ToArray())
|
|
return ([System.BitConverter]::ToString($Hash)).Replace("-", "")
|
|
}
|
|
finally {
|
|
$Hasher.Dispose()
|
|
$Stream.Dispose()
|
|
$Graphics.Dispose()
|
|
$Bitmap.Dispose()
|
|
$Icon.Dispose()
|
|
}
|
|
}
|
|
if (-not $Installer) {
|
|
$Installer = Get-ChildItem `
|
|
-LiteralPath (Join-Path $ProjectRoot "dist") `
|
|
-Filter "DoctorWorkstation-Setup-Windows-x64-*.exe" `
|
|
-File |
|
|
Sort-Object LastWriteTime -Descending |
|
|
Select-Object -First 1 -ExpandProperty FullName
|
|
}
|
|
if (-not $Installer -or -not (Test-Path -LiteralPath $Installer -PathType Leaf)) {
|
|
throw "Windows installer was not found: $Installer"
|
|
}
|
|
$Installer = (Resolve-Path -LiteralPath $Installer).Path
|
|
$InstallerIconHash = Get-AssociatedIconHash -FilePath $Installer
|
|
|
|
$TempBase = [System.IO.Path]::GetFullPath([System.IO.Path]::GetTempPath())
|
|
$SmokeRoot = [System.IO.Path]::GetFullPath((Join-Path $TempBase (
|
|
"doctor-workstation-installer-smoke-" + [guid]::NewGuid().ToString("N")
|
|
)))
|
|
if (-not $SmokeRoot.StartsWith($TempBase, [System.StringComparison]::OrdinalIgnoreCase) -or
|
|
-not ([System.IO.Path]::GetFileName($SmokeRoot)).StartsWith(
|
|
"doctor-workstation-installer-smoke-"
|
|
)) {
|
|
throw "Refusing to use an unsafe installer smoke directory: $SmokeRoot"
|
|
}
|
|
|
|
$InstallDirectory = Join-Path $SmokeRoot "install"
|
|
$SetupLog = Join-Path $SmokeRoot "setup.log"
|
|
$UninstallLog = Join-Path $SmokeRoot "uninstall.log"
|
|
New-Item -ItemType Directory -Path $SmokeRoot -Force | Out-Null
|
|
|
|
$SetupProcess = Start-Process `
|
|
-FilePath $Installer `
|
|
-ArgumentList @(
|
|
"/VERYSILENT",
|
|
"/SUPPRESSMSGBOXES",
|
|
"/NORESTART",
|
|
"/CURRENTUSER",
|
|
"/DIR=$InstallDirectory",
|
|
"/MERGETASKS=!desktopicon",
|
|
"/LOG=$SetupLog"
|
|
) `
|
|
-Wait `
|
|
-PassThru `
|
|
-WindowStyle Hidden
|
|
if ($SetupProcess.ExitCode -ne 0) {
|
|
throw "Installer exited with code $($SetupProcess.ExitCode). See $SetupLog"
|
|
}
|
|
|
|
$InstalledExecutable = Join-Path $InstallDirectory "DoctorWorkstation.exe"
|
|
if (-not (Test-Path -LiteralPath $InstalledExecutable -PathType Leaf)) {
|
|
throw "Installed executable is missing: $InstalledExecutable"
|
|
}
|
|
$Uninstaller = Join-Path $InstallDirectory "unins000.exe"
|
|
if (-not (Test-Path -LiteralPath $Uninstaller -PathType Leaf)) {
|
|
throw "Uninstaller is missing: $Uninstaller"
|
|
}
|
|
$InstalledIconHash = Get-AssociatedIconHash -FilePath $InstalledExecutable
|
|
$UninstallerIconHash = Get-AssociatedIconHash -FilePath $Uninstaller
|
|
if ($InstalledIconHash -ne $InstallerIconHash) {
|
|
throw "Installed executable icon does not match the installer brand icon"
|
|
}
|
|
if ($UninstallerIconHash -ne $InstallerIconHash) {
|
|
throw "Uninstaller icon does not match the installer brand icon"
|
|
}
|
|
|
|
$Environment = @{
|
|
"DOCTOR_CONFIG_DIR" = (Join-Path $SmokeRoot "config")
|
|
"DOCTOR_LOG_DIR" = (Join-Path $SmokeRoot "logs")
|
|
"DOCTOR_API_BASE_URL" = "https://127.0.0.1:9"
|
|
"DOCTOR_DEMO_MODE" = "true"
|
|
"DOCTOR_VIDEO_MODE" = "embedded"
|
|
"DOCTOR_SMOKE_TEST" = "1"
|
|
"QT_QPA_PLATFORM" = "offscreen"
|
|
}
|
|
$PreviousEnvironment = @{}
|
|
$ApplicationExitCode = $null
|
|
$UninstallExitCode = $null
|
|
try {
|
|
foreach ($Name in $Environment.Keys) {
|
|
$PreviousEnvironment[$Name] = [Environment]::GetEnvironmentVariable($Name, "Process")
|
|
[Environment]::SetEnvironmentVariable($Name, $Environment[$Name], "Process")
|
|
}
|
|
$ApplicationProcess = Start-Process `
|
|
-FilePath $InstalledExecutable `
|
|
-ArgumentList "--smoke-test" `
|
|
-Wait `
|
|
-PassThru `
|
|
-WindowStyle Hidden
|
|
$ApplicationExitCode = $ApplicationProcess.ExitCode
|
|
}
|
|
finally {
|
|
foreach ($Name in $Environment.Keys) {
|
|
[Environment]::SetEnvironmentVariable($Name, $PreviousEnvironment[$Name], "Process")
|
|
}
|
|
if (Test-Path -LiteralPath $Uninstaller -PathType Leaf) {
|
|
$UninstallProcess = Start-Process `
|
|
-FilePath $Uninstaller `
|
|
-ArgumentList @(
|
|
"/VERYSILENT",
|
|
"/SUPPRESSMSGBOXES",
|
|
"/NORESTART",
|
|
"/LOG=$UninstallLog"
|
|
) `
|
|
-Wait `
|
|
-PassThru `
|
|
-WindowStyle Hidden
|
|
$UninstallExitCode = $UninstallProcess.ExitCode
|
|
}
|
|
}
|
|
if ($ApplicationExitCode -ne 0) {
|
|
throw "Installed application smoke test exited with code $ApplicationExitCode"
|
|
}
|
|
if ($UninstallExitCode -ne 0) {
|
|
throw "Uninstaller exited with code $UninstallExitCode. See $UninstallLog"
|
|
}
|
|
Start-Sleep -Milliseconds 500
|
|
if (Test-Path -LiteralPath $InstalledExecutable) {
|
|
throw "Uninstaller left the installed executable behind: $InstalledExecutable"
|
|
}
|
|
|
|
Write-Host "Installer icon/install/start/uninstall smoke test passed." -ForegroundColor Green
|
|
Write-Host "Smoke logs and isolated user data: $SmokeRoot"
|