# _precompile.ps1 -Prg - regenereaza .fxp-ul target intr-un proces IZOLAT. # De ce izolat: precompilarea (vfp9 -A ... COMPILE) atarna dupa COMPILE si e omorata; daca # ruleaza in ACEEASI sesiune powershell care lanseaza apoi testul, lansarile ulterioare de # vfp9 esueaza (deschid editorul in loc sa ruleze). Rulat ca proces separat (Start-Process # -Wait din harness), nu otraveste sesiunea care lanseaza testul. param([Parameter(Mandatory=$true)][string]$Prg) $Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe' $Fxp = [System.IO.Path]::ChangeExtension($Prg, 'fxp') $dir = [System.IO.Path]::GetDirectoryName($Prg) $tmpPrg = Join-Path $dir '_compile_tmp.prg' # prg temporar care compileaza target-ul (COMPILE cu variabila; forma cu literal in ghilimele da eroare) Set-Content -Path $tmpPrg -Value ("lcT = `"$Prg`"`r`nCOMPILE (lcT)`r`nQUIT`r`n") -Encoding ascii # omoara doar vfp9 proprii (linia de comanda contine folderul testului), nu instante straine function Stop-VfpProprii([string]$Marker) { Get-CimInstance Win32_Process -Filter "Name='vfp9.exe'" -ErrorAction SilentlyContinue | ForEach-Object { if ($_.CommandLine -and $_.CommandLine.ToLower().Contains($Marker.ToLower())) { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } } } Stop-VfpProprii $dir Start-Sleep -Milliseconds 500 if (Test-Path $Fxp) { [System.IO.File]::Delete($Fxp) } # Fara furt de focus: fereastra vfp9 a compilarii (chiar tranzitorie) e impinsa off-screen, # la fel ca in vfp_ui_harness.ps1 (SetWindowPos HWND_BOTTOM + NOACTIVATE, x=-4000). Add-Type @" using System; using System.Runtime.InteropServices; public class Win32UiPc { [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern bool IsWindow(IntPtr hWnd); public static readonly IntPtr HWND_BOTTOM = new IntPtr(1); public const uint SWP_NOSIZE = 0x0001; public const uint SWP_NOACTIVATE = 0x0010; } "@ function Push-OffscreenPc([IntPtr]$Hwnd) { if ($Hwnd -eq [IntPtr]::Zero -or -not [Win32UiPc]::IsWindow($Hwnd)) { return } [Win32UiPc]::SetWindowPos($Hwnd, [Win32UiPc]::HWND_BOTTOM, -4000, 0, 0, 0, ([Win32UiPc]::SWP_NOSIZE -bor [Win32UiPc]::SWP_NOACTIVATE)) | Out-Null } $ok = $false foreach ($try in 1..3) { $pcProc = Start-Process -FilePath $Vfp -ArgumentList @('-A', "`"$tmpPrg`"") -PassThru $dl = (Get-Date).AddSeconds(30) $pcHwnd = [IntPtr]::Zero while (-not (Test-Path $Fxp) -and (Get-Date) -lt $dl) { if ($pcHwnd -eq [IntPtr]::Zero -and -not $pcProc.HasExited) { $pcProc.Refresh() if ($pcProc.MainWindowHandle -ne [IntPtr]::Zero) { $pcHwnd = $pcProc.MainWindowHandle } } Push-OffscreenPc $pcHwnd Start-Sleep -Milliseconds 300 } Start-Sleep -Seconds 3 Stop-VfpProprii $dir Start-Sleep -Seconds 1 if (Test-Path $Fxp) { $ok = $true; break } } foreach ($f in @($tmpPrg, [System.IO.Path]::ChangeExtension($tmpPrg, 'fxp'))) { if (Test-Path $f) { try { [System.IO.File]::Delete($f) } catch {} } } if ($ok) { exit 0 } else { exit 1 }