path:
/test_typing.ps1
2.98 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
# Windows integration test: keyboard latency while a large pipe remains open.
$ErrorActionPreference = 'Stop'
Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class NativeTyping {
[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);
[DllImport("user32.dll", EntryPoint="SendMessageW", CharSet=CharSet.Unicode)] public static extern IntPtr SetText(IntPtr hwnd, uint msg, IntPtr wp, string text);
[DllImport("user32.dll", EntryPoint="SendMessageW", CharSet=CharSet.Unicode)] public static extern IntPtr ReadText(IntPtr hwnd, uint msg, IntPtr size, System.Text.StringBuilder text);
[DllImport("user32.dll")] public static extern bool PostMessage(IntPtr hwnd, uint msg, IntPtr wp, IntPtr lp);
}
'@
$p = [Diagnostics.Process]::new()
$p.StartInfo.FileName = (Join-Path $PSScriptRoot 'wmenu.exe')
$p.StartInfo.UseShellExecute = $false
$p.StartInfo.RedirectStandardInput = $true
$p.StartInfo.RedirectStandardOutput = $true
try {
[void]$p.Start()
for ($i = 0; $i -lt 20000; $i++) { $p.StandardInput.WriteLine("streamed-$i " + ('x' * 300)) }
$p.StandardInput.Flush()
$list = [IntPtr]::Zero
for ($i = 0; $i -lt 100; $i++) {
Start-Sleep -Milliseconds 50
$p.Refresh()
$list = [NativeTyping]::FindWindowEx($p.MainWindowHandle, [IntPtr]::Zero, 'ListBox', $null)
if ($list -ne [IntPtr]::Zero -and [NativeTyping]::SendMessage($list, 0x18B, [IntPtr]::Zero, [IntPtr]::Zero).ToInt32() -ge 20000) { break }
}
if ($list -eq [IntPtr]::Zero -or [NativeTyping]::SendMessage($list, 0x18B, [IntPtr]::Zero, [IntPtr]::Zero).ToInt32() -lt 20000) { throw 'Stream did not load while pipe was open' }
$edit = [NativeTyping]::FindWindowEx($p.MainWindowHandle, [IntPtr]::Zero, 'Edit', $null)
if ($edit -eq [IntPtr]::Zero) { throw 'No edit control' }
[void][NativeTyping]::SetText($edit, 0xC, [IntPtr]::Zero, 'streamed')
[void][NativeTyping]::SendMessage($edit, 0xB1, [IntPtr]8, [IntPtr]8)
$worst = 0
for ($i = 1; $i -le 12; $i++) {
$clock = [Diagnostics.Stopwatch]::StartNew()
[void][NativeTyping]::PostMessage($edit, 0x102, [IntPtr][int][char]'a', [IntPtr]::Zero)
do {
Start-Sleep -Milliseconds 1
$buffer = [Text.StringBuilder]::new(80)
[void][NativeTyping]::ReadText($edit, 0xD, [IntPtr]$buffer.Capacity, $buffer)
if ($clock.ElapsedMilliseconds -gt 250) { throw "Typing stalled at character $i; got '$($buffer.ToString())'" }
} while ($buffer.ToString() -ne ('streamed' + ('a' * $i)))
if ($clock.ElapsedMilliseconds -gt $worst) { $worst = $clock.ElapsedMilliseconds }
}
Write-Output "Worst character latency: ${worst}ms with 20,000 streamed rows (pipe still open)."
} finally {
if (!$p.HasExited) { $p.Kill(); $p.WaitForExit() }
$p.Dispose()
}