$ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot $tempRoot = [System.IO.Path]::GetFullPath((Join-Path $root 'temp')) $work = Join-Path $tempRoot ('hta-hidden-' + [guid]::NewGuid().ToString('N')) $hta = Join-Path $work 'MassMailer.hta' $started = $null try { $null = New-Item -ItemType Directory -Path $work -Force Copy-Item -LiteralPath (Join-Path $root 'tools') -Destination (Join-Path $work 'tools') -Recurse Copy-Item -LiteralPath (Join-Path $root 'src') -Destination (Join-Path $work 'src') -Recurse $null = New-Item -ItemType Directory -Path (Join-Path $work 'templates') -Force $app = Get-Content -LiteralPath (Join-Path $root 'MassMailer.hta') -Raw $app.Replace('APPLICATIONNAME="MassMailer"', 'APPLICATIONNAME="MassMailerSmoke"') | Set-Content -LiteralPath $hta -Encoding UTF8 $dbPath = Join-Path $work 'data\test.mdb' $null = New-Item -ItemType Directory -Path (Split-Path -Parent $dbPath) -Force $settings = Get-Content -LiteralPath (Join-Path $root 'config.example.ini') -Raw $settings.Replace('DB_PATH=data/MassMailer.mdb', ('DB_PATH=' + $dbPath)) | Set-Content -LiteralPath (Join-Path $work 'config.ini') -Encoding UTF8 $cscript = Join-Path $env:SystemRoot 'SysWOW64\cscript.exe' & $cscript //nologo (Join-Path $work 'tools\init-db.vbs') (Join-Path $work 'config.ini') if ($LASTEXITCODE -ne 0) { throw 'Isolated MDB initialization failed' } $mshta = Join-Path $env:SystemRoot 'SysWOW64\mshta.exe' $started = Start-Process -FilePath $mshta -ArgumentList ('"' + $hta + '"') -PassThru -WindowStyle Hidden $session = $null for ($wait = 0; $wait -lt 30; $wait++) { Start-Sleep -Seconds 1 $matches = @(Get-CimInstance Win32_Process -Filter "Name='mshta.exe'" | Where-Object { $_.CommandLine -and $_.CommandLine.IndexOf($hta, [StringComparison]::OrdinalIgnoreCase) -ge 0 }) if ($matches.Count -eq 1) { $session = Join-Path $work ('temp\session-' + $matches[0].ProcessId + '.txt') if (Test-Path -LiteralPath $session -PathType Leaf) { break } } } if ($matches.Count -ne 1 -or -not (Test-Path -LiteralPath $session -PathType Leaf)) { throw 'Isolated HTA did not initialize its hidden dispatcher session' } Start-Sleep -Seconds 3 Write-Output 'Isolated HTA startup passed while the main app remained open' } finally { $matches = @(Get-CimInstance Win32_Process -Filter "Name='mshta.exe'" | Where-Object { $_.CommandLine -and $_.CommandLine.IndexOf($hta, [StringComparison]::OrdinalIgnoreCase) -ge 0 }) foreach ($process in $matches) { Stop-Process -Id $process.ProcessId -Force -ErrorAction SilentlyContinue } $resolvedWork = [System.IO.Path]::GetFullPath($work) if (-not $resolvedWork.StartsWith($tempRoot + [System.IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { throw 'Unsafe isolated test cleanup path' } if (Test-Path -LiteralPath $resolvedWork) { Remove-Item -LiteralPath $resolvedWork -Recurse -Force } }