# 2b V6/V7 proof target: a dedicated WinForms window we own. # ASCII-only source (PS 5.1 decodes BOM-less .ps1 as GBK; see personal lessons). # # Launched by text_injection_proof.ps1. Shows a topmost empty TextBox, writes # its current text to ResultFile (UTF-8 with BOM) on every change, exits when # StopFile appears. The proof injects through the remote-control pipeline and # polls ResultFile - so "what arrived on the controlled desktop" is reported # by the receiving application itself, not by a screenshot or OCR. param( [Parameter(Mandatory = $true)][string]$PidFile, [Parameter(Mandatory = $true)][string]$ResultFile, [Parameter(Mandatory = $true)][string]$StopFile ) $ErrorActionPreference = "Stop" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # Event handler scriptblocks resolve script-scoped vars; make that explicit # instead of relying on the param locals staying on a visible scope chain. $script:PidFile = $PidFile $script:ResultFile = $ResultFile $script:StopFile = $StopFile $script:lastWritten = $null $form = New-Object System.Windows.Forms.Form $form.Text = "RemoteTextTarget" $form.ClientSize = New-Object System.Drawing.Size(420, 140) $form.TopMost = $true $form.StartPosition = "Manual" $form.Location = New-Object System.Drawing.Point(80, 80) $tb = New-Object System.Windows.Forms.TextBox $tb.Multiline = $true $tb.Font = New-Object System.Drawing.Font("Segoe UI", 16.0) $tb.Dock = "Fill" $form.Controls.Add($tb) $timer = New-Object System.Windows.Forms.Timer $timer.Interval = 150 $timer.Add_Tick({ if (Test-Path $script:StopFile) { $form.Close() return } if ($tb.Text -ne $script:lastWritten) { $script:lastWritten = $tb.Text $enc = New-Object System.Text.UTF8Encoding($true) [System.IO.File]::WriteAllText($script:ResultFile, $tb.Text, $enc) } if (-not $tb.Focused) { [void]$tb.Focus() } }) $form.Add_Shown({ $form.Activate() [void]$tb.Focus() [System.IO.File]::WriteAllText($script:PidFile, "$PID") }) $timer.Start() [void]$form.ShowDialog() $timer.Stop()