A tiny, dependency-free command-line utility for capturing a screenshot of the current display while running inside Windows PE (Preinstallation Environment).
Windows PE is a minimal boot environment used for OS deployment, imaging, and repair — it doesn't include the Snipping Tool, Print Screen clipboard support, or any of the usual Windows screenshot tooling. When you're debugging a boot script, an unattended install sequence, or a driver issue that only shows up in PE, there's normally no easy way to capture what's on screen.
WinPEScreenshot fills that gap: a single small .exe that can be dropped into a WinPE image (or run from a USB stick) to grab the full screen and save it as a .bmp file, with no external dependencies beyond what PE already ships.
- Captures the full screen via the Win32 GDI API (
BitBlt/GetDIBits) - Writes a standard, uncompressed 24-bit BMP file — viewable anywhere, no codecs required
- Smart default output location:
Screenshots\next to the.exe(usually the USB stick you ran it from), falling back to the first writable volume, then the WinPE RAM disk (X:\) - Auto-generates timestamped filenames (
YYYYMMDD_HHMMSS.bmp) so repeated captures never overwrite each other - Explicit output paths, including UNC network shares (
\\server\logs$\shot.bmp) — missing directories are created automatically - Delayed capture (
-d 5) so you can bring up the dialog or menu you want to document - Hotkey mode (
-k): stays resident and captures on every PrintScreen press for the whole PE session - Hides its own console window during capture, so the shot shows what you care about
- Clear error messages (Win32 error text) plus script-friendly exit codes
- Single static executable — no runtime, no installer; x64, x86, and ARM64 builds
WinPEScreenshot.exe [options] [outfile.bmp | outdir]
| Option | Meaning |
|---|---|
-d, --delay <sec> |
Wait <sec> seconds before capturing |
-k, --hotkey |
Stay resident; capture on PrintScreen, Ctrl+C quits |
-h, -?, --help |
Show help |
--version |
Show version |
With no path, a timestamped .bmp is saved to the first writable location out of:
Screenshots\next toWinPEScreenshot.exe— if you ran it from a USB stick, the shots land on that stick<drive>:\Screenshotson the first writable fixed/removable volumeX:\Screenshotson the WinPE RAM disk (last resort — contents vanish on reboot)
If the path you pass is an existing directory (or ends with \), a timestamped file is written inside it; otherwise it's used as the output filename. Missing directories are created automatically, and UNC paths work — handy when the deployment share is already mapped:
WinPEScreenshot.exe Timestamped shot, default location
WinPEScreenshot.exe D:\myshot.bmp Explicit filename
WinPEScreenshot.exe -d 5 \\server\logs$\setup.bmp 5s delay, straight to a network share
WinPEScreenshot.exe -k E:\Screenshots\ PrintScreen-to-capture for the whole session
In hotkey mode the key is plain PrintScreen in WinPE. On full Windows 11 the PrintScreen key is normally bound to the Snipping Tool — a low-level hook eats the key before registered hotkeys ever see it — so there the tool registers Ctrl+PrintScreen instead and says so at startup.
The utility hides its own console window (classic conhost, which is what WinPE uses) while the shot is taken and restores it afterwards, so the console does not appear in the capture. Under ConPTY-based terminals on full Windows (Windows Terminal, VS Code) the visible window belongs to the terminal app rather than the console session and can't be hidden this way — if that matters, use -d and minimize the window during the delay. Relatedly, when launching the exe spawns a brand-new console (double-clicking it, start, etc.), a no-delay capture fires before that console has painted anything, so it shows up as, at most, an empty frame.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Screen capture (BitBlt) failed |
| 2 | Pixel readback (GetDIBits) failed |
| 3 | Could not create/write output file |
| 4 | No writable output location found |
| 5 | Bad arguments / hotkey registration failed |
Failures also print the Win32 error text (e.g. Access is denied vs The system cannot find the path specified) to stderr.
Prebuilt WinPEScreenshot-x64.exe, WinPEScreenshot-x86.exe, and WinPEScreenshot-arm64.exe binaries are on the Releases page (built automatically by GitHub Actions). Pick the one matching your PE image's architecture, or just run it from removable media while booted into PE.
To bake it into the image with DISM:
dism /Mount-Image /ImageFile:winpe.wim /Index:1 /MountDir:C:\mount
copy WinPEScreenshot-x64.exe C:\mount\Windows\System32\WinPEScreenshot.exe
dism /Unmount-Image /MountDir:C:\mount /CommitTo start hotkey mode automatically for the whole PE session, add it to startnet.cmd (inside the image at Windows\System32\startnet.cmd):
wpeinit
start "" WinPEScreenshot.exe -kOr, if you use winpeshl.ini instead:
[LaunchApps]
%SYSTEMDRIVE%\Windows\System32\WinPEScreenshot.exe, -k
%SYSTEMDRIVE%\Windows\System32\startnet.cmdA single C++ source file using only the Win32 API — compile with the Windows SDK / Visual Studio Build Tools:
rc /nologo WinPEScreenshot.rc
cl /nologo /W4 /O1 /MT /EHsc WinPEScreenshot.cpp /link user32.lib gdi32.lib advapi32.lib WinPEScreenshot.res
(/MT statically links the CRT, which matters in PE — there's no VC redistributable there. The .rc step embeds the version-info resource; it's optional if you just want a working exe.)
CI builds all three architectures on every push, and tagging v* publishes them to Releases.
MIT