$ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot $hta = Join-Path $root 'MassMailer.hta' $mshta = Join-Path $env:SystemRoot 'SysWOW64\mshta.exe' $existing = @(Get-CimInstance Win32_Process -Filter "Name='mshta.exe'" | Where-Object { $_.CommandLine -like '*MassMailer.hta*' }) if ($existing.Count) { throw 'Close the existing MassMailer HTA before this startup smoke test' } $started = $null try { $started = Start-Process -FilePath $mshta -ArgumentList ('"' + $hta + '"') -PassThru -WindowStyle Hidden $active = @() $session = $null for ($wait = 0; $wait -lt 25; $wait++) { Start-Sleep -Seconds 1 $active = @(Get-CimInstance Win32_Process -Filter "Name='mshta.exe'" | Where-Object { $_.CommandLine -like '*MassMailer.hta*' }) if ($active.Count -eq 1) { $session = Join-Path $root ('temp\session-' + $active[0].ProcessId + '.txt') if (Test-Path -LiteralPath $session -PathType Leaf) { break } } } if ($active.Count -ne 1) { throw 'Expected one running MassMailer HTA process' } if (-not (Test-Path -LiteralPath $session -PathType Leaf)) { throw 'HTA did not create an active dispatcher session heartbeat' } if ((Get-Item -LiteralPath $session).LastWriteTimeUtc -lt [DateTime]::UtcNow.AddSeconds(-20)) { throw 'HTA dispatcher heartbeat is stale' } $powerShellX86 = Join-Path $env:SystemRoot 'SysWOW64\WindowsPowerShell\v1.0\powershell.exe' $token = [System.IO.File]::ReadAllText($session).Trim() & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'test-session-guard.ps1') -SessionPid $active[0].ProcessId -SessionToken $token if ($LASTEXITCODE -ne 0) { throw 'Open-window process guard rejected the active HTA' } Write-Output 'Hidden HTA startup and open-window dispatcher session passed' } finally { $active = @(Get-CimInstance Win32_Process -Filter "Name='mshta.exe'" | Where-Object { $_.CommandLine -like '*MassMailer.hta*' }) foreach ($process in $active) { if ($process.ProcessId -notin @($existing | ForEach-Object ProcessId)) { Stop-Process -Id $process.ProcessId -Force -ErrorAction SilentlyContinue $session = Join-Path $root ('temp\session-' + $process.ProcessId + '.txt') $full = [System.IO.Path]::GetFullPath($session) $tempRoot = [System.IO.Path]::GetFullPath((Join-Path $root 'temp')) if ($full.StartsWith($tempRoot + [System.IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase) -and (Test-Path -LiteralPath $full)) { Remove-Item -LiteralPath $full -Force } } } }