path:
/test_pipe.ps1
2.71 KB | plain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ErrorActionPreference = 'Stop'
Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class NativeMenu {
[DllImport("user32.dll", CharSet=CharSet.Unicode)] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr after, string cls, string title);
[DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wp, IntPtr lp);
}
'@
$p = New-Object System.Diagnostics.Process
$p.StartInfo.FileName = (Join-Path $PSScriptRoot 'wmenu.exe')
$p.StartInfo.UseShellExecute = $false
$p.StartInfo.RedirectStandardInput = $true
$p.StartInfo.RedirectStandardOutput = $true
try {
if (-not $p.Start()) { throw 'Could not start wmenu' }
$p.StandardInput.WriteLine('first-streamed-line')
$p.StandardInput.Flush()
$count = -1
for ($i = 0; $i -lt 100; $i++) {
Start-Sleep -Milliseconds 50
$p.Refresh()
$win = $p.MainWindowHandle
if ($win -ne [IntPtr]::Zero) {
$list = [NativeMenu]::FindWindowEx($win, [IntPtr]::Zero, 'ListBox', $null)
if ($list -ne [IntPtr]::Zero) {
$count = [NativeMenu]::SendMessage($list, 0x18B, [IntPtr]::Zero, [IntPtr]::Zero).ToInt32()
if ($count -gt 0) { break }
}
}
}
if ($count -ne 1) { throw "Expected row before pipe closes; got $count, hwnd=$win, list=$list, exited=$($p.HasExited)" }
$p.StandardInput.WriteLine('long-' + ('x' * 8192))
for ($j = 0; $j -lt 3000; $j++) { $p.StandardInput.WriteLine("streamed-$j") }
$p.StandardInput.Flush()
$more = 0
for ($i = 0; $i -lt 100 -and $more -lt 3002; $i++) {
Start-Sleep -Milliseconds 50
$more = [NativeMenu]::SendMessage($list, 0x18B, [IntPtr]::Zero, [IntPtr]::Zero).ToInt32()
}
if ($more -ne 3002) { throw "Expected 3,002 rows including one long line before EOF; got $more" }
$edit = [NativeMenu]::FindWindowEx($win, [IntPtr]::Zero, 'Edit', $null)
if ($edit -eq [IntPtr]::Zero) { throw 'No edit control' }
[void][NativeMenu]::SendMessage($list, 0x186, [IntPtr]1, [IntPtr]::Zero) # LB_SETCURSEL
if ([NativeMenu]::SendMessage($list, 0x188, [IntPtr]::Zero, [IntPtr]::Zero).ToInt32() -ne 1) { throw 'Could not select the long line' }
$output = $p.StandardOutput.ReadToEndAsync()
[void][NativeMenu]::SendMessage($edit, 0x100, [IntPtr]13, [IntPtr]::Zero) # WM_KEYDOWN, Enter
if (-not $p.WaitForExit(5000)) { throw 'wmenu did not exit after Enter' }
if ($output.GetAwaiter().GetResult() -ne ('long-' + ('x' * 8192))) { throw 'Long row was not preserved on stdout' }
Write-Output "List showed $more complete rows before EOF; long row output intact."
} finally {
if (-not $p.HasExited) { $p.Kill(); $p.WaitForExit() }
$p.Dispose()
}