# Capture a window (by title substring) or the full virtual screen to a PNG. # Usage: powershell -File shot.ps1 [titleSubstring] param([string]$Out = "shot.png", [string]$Title = "") Add-Type -AssemblyName System.Windows.Forms, System.Drawing Add-Type @" using System; using System.Runtime.InteropServices; public class W { [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr h, out R r); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h); [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr h); [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr h, System.Text.StringBuilder s, int n); [DllImport("user32.dll")] public static extern bool EnumWindows(EnumProc cb, IntPtr p); public delegate bool EnumProc(IntPtr h, IntPtr p); public struct R { public int L, T, Rr, B; } } "@ function Cap($rect, $path) { $w = $rect.Rr - $rect.L; $h = $rect.B - $rect.T if ($w -le 0 -or $h -le 0) { return $false } $bmp = New-Object System.Drawing.Bitmap $w, $h $g = [System.Drawing.Graphics]::FromImage($bmp) $g.CopyFromScreen($rect.L, $rect.T, 0, 0, (New-Object System.Drawing.Size($w, $h))) $bmp.Save($path, [System.Drawing.Imaging.ImageFormat]::Png) $g.Dispose(); $bmp.Dispose(); return $true } if ($Title -ne "") { $found = @() $cb = [W+EnumProc]{ param($h,$p) if ([W]::IsWindowVisible($h)) { $sb = New-Object System.Text.StringBuilder 256 [void][W]::GetWindowText($h, $sb, 256) $t = $sb.ToString() if ($t -like "*$Title*") { $script:found += @{H=$h; T=$t} } } return $true } [void][W]::EnumWindows($cb, [IntPtr]::Zero) Write-Host "Matched windows:"; $found | ForEach-Object { Write-Host " '$($_.T)'" } $i = 0 foreach ($f in $found) { $r = New-Object W+R; [void][W]::GetWindowRect($f.H, [ref]$r) [void][W]::SetForegroundWindow($f.H); Start-Sleep -Milliseconds 250 $p = $Out -replace '\.png$', "_$i.png" if (Cap $r $p) { Write-Host "saved $p ($($r.Rr-$r.L)x$($r.B-$r.T)) '$($f.T)'" } $i++ } } else { $vs = [System.Windows.Forms.SystemInformation]::VirtualScreen $r = New-Object W+R; $r.L=$vs.Left; $r.T=$vs.Top; $r.Rr=$vs.Right; $r.B=$vs.Bottom [void](Cap $r $Out); Write-Host "saved $Out (full screen $($vs.Width)x$($vs.Height))" }