Release v0.5.0: isolate screenshot editor and support manifest-based updates
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
param([string]$Executable = "$PSScriptRoot\..\build\staged\KSwitcher.Screenshot.exe")
|
||||
$ErrorActionPreference='Stop'
|
||||
if (Get-Process KSwitcher.Screenshot -ErrorAction SilentlyContinue) { throw 'Close existing screenshot editors before this test.' }
|
||||
Add-Type @'
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
public static class ScreenshotProcessTest {
|
||||
public delegate bool EnumProc(IntPtr w, IntPtr p);
|
||||
[DllImport("user32.dll")] static extern bool EnumWindows(EnumProc callback, IntPtr param);
|
||||
[DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr w, out uint pid);
|
||||
[DllImport("user32.dll", CharSet=CharSet.Unicode)] static extern int GetClassName(IntPtr w, StringBuilder name, int count);
|
||||
[DllImport("user32.dll", CharSet=CharSet.Unicode)] static extern int GetWindowText(IntPtr w, StringBuilder name, int count);
|
||||
[DllImport("user32.dll")] public static extern bool PostMessage(IntPtr w, uint msg, IntPtr wp, IntPtr lp);
|
||||
public static IntPtr[] Windows(int process, string cls) {
|
||||
var windows=new List<IntPtr>();
|
||||
EnumWindows((w,p)=>{ uint pid; GetWindowThreadProcessId(w,out pid);
|
||||
var name=new StringBuilder(256); GetClassName(w,name,256);
|
||||
if(pid==process && name.ToString()==cls) windows.Add(w); return true;
|
||||
},IntPtr.Zero); return windows.ToArray();
|
||||
}
|
||||
public static string Title(IntPtr w) { var s=new StringBuilder(256); GetWindowText(w,s,256); return s.ToString(); }
|
||||
}
|
||||
'@
|
||||
function Wait-For([scriptblock]$Check,[string]$Message) {
|
||||
for($attempt=0;$attempt -lt 100;$attempt++) { if (& $Check) { return }; Start-Sleep -Milliseconds 50 }
|
||||
throw $Message
|
||||
}
|
||||
function Send($Window,$Message,$Wparam=0,$Lparam=0) {
|
||||
[ScreenshotProcessTest]::PostMessage($Window,$Message,[IntPtr]$Wparam,[IntPtr]$Lparam) | Out-Null
|
||||
}
|
||||
function Capture-Windows { @([ScreenshotProcessTest]::Windows($script:process.Id,'KSwitcher.Capture')) }
|
||||
function Select-Region($Window) {
|
||||
Send $Window 0x201 1 ((40 -shl 16) -bor 40)
|
||||
Send $Window 0x200 1 ((240 -shl 16) -bor 360)
|
||||
Send $Window 0x202 0 ((240 -shl 16) -bor 360)
|
||||
Wait-For { [ScreenshotProcessTest]::Title($Window) -match 'Screenshot #' } 'Selection did not become an editor.'
|
||||
}
|
||||
function Close-Editor($Window) {
|
||||
Send $Window 0x10
|
||||
Wait-For { @([ScreenshotProcessTest]::Windows($script:process.Id,'#32770')).Count -eq 1 } 'Missing close confirmation.'
|
||||
$dialog=[ScreenshotProcessTest]::Windows($script:process.Id,'#32770')[0]
|
||||
Send $dialog (0x400+102) 6 # TDM_CLICK_BUTTON / IDYES; no clipboard writes.
|
||||
Wait-For { (Capture-Windows) -notcontains $Window } 'Editor did not close.'
|
||||
}
|
||||
$process=$null
|
||||
try {
|
||||
$process=Start-Process -FilePath $Executable -WindowStyle Hidden -PassThru
|
||||
Wait-For { (Capture-Windows).Count -eq 1 } 'First selection did not open.'
|
||||
$first=(Capture-Windows)[0]; Select-Region $first
|
||||
$secondLaunch=Start-Process -FilePath $Executable -WindowStyle Hidden -PassThru
|
||||
if (!$secondLaunch.WaitForExit(10000) -or $secondLaunch.ExitCode -ne 0) { throw 'Second launch did not hand off.' }
|
||||
Wait-For { (Capture-Windows).Count -eq 2 } 'Second selection did not open in same process.'
|
||||
$second=(Capture-Windows | Where-Object { $_ -ne $first })[0]; Select-Region $second
|
||||
if ([ScreenshotProcessTest]::Title($first) -eq [ScreenshotProcessTest]::Title($second)) { throw 'Editor indices collide.' }
|
||||
Close-Editor $first
|
||||
if ($process.HasExited) { throw 'Process exited with an editor open.' }
|
||||
Close-Editor $second
|
||||
if (!$process.WaitForExit(5000) -or $process.ExitCode -ne 0) { throw 'Last editor did not exit process.' }
|
||||
$process=Start-Process -FilePath $Executable -WindowStyle Hidden -PassThru
|
||||
Wait-For { (Capture-Windows).Count -eq 1 } 'New process did not open selection.'
|
||||
Send (Capture-Windows)[0] 0x100 27 # Esc cancels a selection only.
|
||||
if (!$process.WaitForExit(5000) -or $process.ExitCode -ne 0) { throw 'Cancelling selection did not exit process.' }
|
||||
'Passed screenshot process lifecycle checks'
|
||||
} finally {
|
||||
if ($process -and !$process.HasExited) { Stop-Process -Id $process.Id }
|
||||
}
|
||||
Reference in New Issue
Block a user