A professional snipping tool for Windows 11 written in pure PowerShell 7.5+ on .NET 9. Hover-to-highlight smart capture, magnifier loupe, floating widget, system tray, chromeless Fluent preview with a full annotation editor — all in a single script with zero external dependencies and no admin elevation.
- Smart capture — hover any window to highlight it and click to grab, or drag for a custom region. One overlay, two gestures, with a pixel-perfect magnifier loupe and live screen-coordinate readout.
- Full virtual-desktop capture spanning all monitors (handles negative-origin layouts).
- Active window capture — grabs the foreground window by its exact window rect.
- Per-monitor DPI aware — accurate capture at 100 % / 125 % / 150 % / 200 %.
- Chromeless Fluent UI — WPF Fluent theme, Segoe Fluent Icons, draggable header, pin-on-top, resizable, maximizable.
- Zoom — Zoom In / Zoom Out / Fit-to-viewport buttons,
Ctrl + +,Ctrl + -,Ctrl + 0, and Ctrl + mouse-wheel all work. Range 5 % – 1000 %. Live zoom indicator in the header. - Pan (Hand) mode — the default when no annotation tool is selected: click and drag anywhere on the image to scroll a zoomed-in view. Cursor auto-switches between Hand and Cross.
- Four annotation tools: Highlight, Rectangle, Arrow, Text
- Six-color palette (yellow / green / pink / blue / orange / red) with live in-place color updates — change color while typing a text annotation and the foreground swaps immediately
- Undo / Redo with full history (
Ctrl+Z/Ctrl+Shift+Z) - Right-click any annotation to change its color or delete it
- Clear all button to wipe the annotation layer
- Annotations are stored in image-pixel coordinates so they survive zoom and export cleanly
- Copy to clipboard — flattened with all annotations baked in (
Ctrl+C) - Save as — PNG / JPG / BMP, default path
~\Pictures\Snips\snip-yyyyMMdd-HHmmss.png(Ctrl+S) - New snip — close the preview and start a fresh capture (
Ctrl+N)
- System tray with full menu (capture modes, open snips folder, about, uninstall, exit)
- Floating capture widget — auto-hiding top-center pill with Smart/Full/Window buttons
- One configurable Smart-capture hotkey registered via
RegisterHotKeyon a hidden message-only form; Full and Window capture stay available from the tray - Single-instance enforced by a per-session named mutex; a second launch shows a friendly message instead of stacking up
- Self-installing: first launch copies the app and durable settings to
%LOCALAPPDATA%\SnipIT, creates a Desktop shortcut, and synchronizes theshell:startupshortcut from theLaunchAtSignInsetting. No admin. No UAC prompts.
| Hotkey | Action |
|---|---|
Ctrl+Alt+Shift+Q |
Smart capture (hover-window or drag-region) |
Esc / right-click |
Cancel an active capture |
Full virtual-desktop and active-window capture intentionally have no global hotkey; use the system-tray menu for those modes.
| Hotkey | Action |
|---|---|
Ctrl+C |
Copy flattened image to clipboard |
Ctrl+S |
Save as PNG / JPG / BMP |
Ctrl+N |
New snip |
Ctrl+Z / Ctrl+Shift+Z |
Undo / Redo |
Ctrl + + / Ctrl + - |
Zoom in / out |
Ctrl + 0 |
Reset zoom to 100 % |
Ctrl + mouse-wheel |
Zoom centered on cursor |
Esc |
Close preview |
- Make sure you have PowerShell 7.5+ and Windows 11 (
pwsh --version) - Download
SnipIT.ps1 - Double-click it (or run
pwsh -Sta -File .\SnipIT.ps1)
On first run SnipIT silently:
- Copies itself to
%LOCALAPPDATA%\SnipIT\SnipIT.ps1 - Creates
%LOCALAPPDATA%\SnipIT\settings.jsonfor the Smart hotkey, save defaults, widget visibility, and launch-at-sign-in preference - Creates a Desktop shortcut
- Creates or removes the
shell:startupshortcut to matchLaunchAtSignIn(enabled by default) - Generates a
SnipIT.icoon the fly - Shows a tray balloon: "SnipIT installed. Press Ctrl+Alt+Shift+Q to capture."
To uninstall: right-click the tray icon → Uninstall. Removes both shortcuts and the %LOCALAPPDATA%\SnipIT folder.
After installation, SnipIT runs in the system tray. Press Ctrl+Alt+Shift+Q, hover the window you want, click. The preview window opens with the captured image. From there:
- Annotate — click a tool, pick a color, drag on the image. Click the active tool again (or
Esc) to return to pan mode. - Zoom in to detail —
Ctrl + mouse-wheelor the zoom buttons; then drag the image to pan around. - Change an existing annotation — right-click it to pick a new color or delete it.
- Type a text annotation — click the Text tool, click on the image, type, click a different color mid-typing to re-color live, press Enter to commit (or click elsewhere). Escape discards.
- Copy or save —
Ctrl+C/Ctrl+S, or the toolbar buttons. - New snip —
Ctrl+Nor the toolbar button to close the preview and drop straight back into the capture overlay.
SnipIT keeps a portable single-file distribution while using modular, reviewable development sources. The ownership and generation flow is:
src/*.ps1 + xaml/*.xaml
│
▼
Build-SnipIT.ps1
│
▼
SnipIT.ps1
src/00-Core.ps1owns cross-platform pure logic and the-CoreOnlyboundary.src/10-Bootstrap.ps1owns startup, settings, installation, and XAML loading.src/20-Native.ps1,src/30-Capture.ps1,src/40-Preview.ps1,src/50-Tray.ps1, andsrc/90-Main.ps1own their named runtime layers.- The six files in
xaml/own UI markup. Build-SnipIT.ps1is the sole authority for module/XAML order and generation.
SnipIT.ps1 is generated, checked in, portable, and has no runtime dependency
on the repository. Never edit it directly; edit src/ or xaml/ and rebuild.
# Run authoritative modular development sources (Windows)
pwsh -Sta -File ./SnipIT.Dev.ps1
# Regenerate the portable checked-in release
pwsh -NoProfile -File ./Build-SnipIT.ps1Commit the regenerated SnipIT.ps1 with every source or XAML change. CI runs
the builder and rejects a stale release with git diff --exit-code -- SnipIT.ps1.
The preview window's mouse interaction, zoom, text-editing and color-picking are all organized as named closures captured at window-creation time ($beginPan, $updatePan, $endPan, $beginDraw, $updateDraw, $finishDraw, $openText, $pickColor, $handleMouseDown, $setZoom, $zoomBy, $fitToViewport). The real WPF event handlers are one-line wrappers that compute mouse positions and delegate to these closures. This keeps the event handlers trivial and — more importantly — gives the test harness a way to drive every code path without synthesizing real MouseButtonEventArgs.
Show-PreviewWindow accepts an optional -TestAction [scriptblock] parameter that runs the callback during Loaded (while ShowDialog is blocking, so function-local variables stay alive) and then closes the window off-screen. The interactive harness uses this to run end-to-end tests against a headless preview window.
Setting the environment variable SNIPIT_TEST_MODE=1 before dot-sourcing the
generated release or development launcher short-circuits installation and
shortcut writes as well as the single-instance mutex, tray setup, hotkey
registration, and main loop, so a harness can load functions without side effects.
All suites are zero-dependency (no Pester). The harness reports current totals at runtime, so this documentation does not become stale as coverage grows.
# Build/generation contract and failure fixtures (any platform)
pwsh -NoProfile -File .\Test-SnipIT-Build.ps1
# Pure-logic suite against the generated release (any platform)
pwsh -NoProfile -File .\Test-SnipIT.ps1
# Pure-logic parity against authoritative development sources
$env:SNIPIT_SCRIPT_UNDER_TEST = '.\SnipIT.Dev.ps1'
pwsh -NoProfile -File .\Test-SnipIT.ps1
# Full generated-release WPF suite (Windows only)
Remove-Item Env:SNIPIT_SCRIPT_UNDER_TEST -ErrorAction Ignore
pwsh -NoProfile -Sta -File .\Test-SnipIT-Interactive.ps1
# Focused development-launcher WPF smoke (Windows only)
$env:SNIPIT_SCRIPT_UNDER_TEST = '.\SnipIT.Dev.ps1'
$env:SNIPIT_TEST_GROUP = 'Floating Studio preview shell'
pwsh -NoProfile -Sta -File .\Test-SnipIT-Interactive.ps1
Remove-Item Env:SNIPIT_TEST_GROUP,Env:SNIPIT_SCRIPT_UNDER_TESTLocks manifest order, module/function parity, embedded XAML parity, deterministic generation, formatting, provenance, parser safety, and transactional failure behavior.
Covers pure logic and behavioral contracts through -CoreOnly, against either
SnipIT.ps1 or the injected SNIPIT_SCRIPT_UNDER_TEST development launcher.
Drives a real off-screen preview window via -TestAction. Coverage:
- Zoom —
SetZoom,ZoomBy, compounded zoom, clamps (0.05 / 10),ZoomTextupdate,FitToViewport - Pan — default Hand cursor, drag →
Scrolleroffset,EndPancursor restore, no-op when not panning - Tool selection — Highlight / Rect / Text interlock, cursor switching
- Drawing — highlight / rect / arrow with coord mapping at 1× and 2× zoom, short-arrow auto-discard
- Colors — all six palette entries applied to new annotations via
ActiveColorand viaPickColor - Undo / Redo
- Hit test —
Find-AnnotationAttopmost wins, outside returns -1 - Flattening —
Get-FlattenedBitmapdimensions and type - Full click dispatch via
HandleMouseDown— pan / draft / text / out-of-bounds / editing-text branches - Text tool —
OpenTextcreates a TextBox; empty commit discards; typed commit appends annotation; livePickColorforeground swap during editing;Render-Annotationsappliesannotation.Colorto the rendered TextBlock
| File / folder | Purpose |
|---|---|
src/ |
Authoritative PowerShell implementation modules |
xaml/ |
Authoritative WPF markup |
Build-SnipIT.ps1 |
Deterministic manifest, embedding, validation, and release generator |
SnipIT.Dev.ps1 |
Development launcher for authoritative repository sources |
SnipIT.ps1 |
Generated, checked-in, standalone distribution; never edit directly |
Test-SnipIT-Build.ps1 |
Build determinism and failure-contract fixtures |
Test-SnipIT.ps1 |
Cross-platform pure-logic tests, no dependencies |
Test-SnipIT-Interactive.ps1 |
Windows WPF integration tests, no dependencies |
docs/ |
Long-form docs (design mocks, deeper write-ups). docs/README.md is the index. |
CHANGELOG.md |
Per-merge change history (Keep a Changelog format). |
SECURITY.md |
Vulnerability disclosure policy + supported versions. |
AGENTS.md |
Authoritative agent/contributor brief and engineering constraints |
CLAUDE.md |
Compatibility pointer to AGENTS.md |
shared/runbooks/engineering-standards.md |
PowerShell variant of the company-canonical engineering-standards runbook. |
.bestpractices.json |
OpenSSF Best Practices self-assessment (project 12647). |
LICENSE |
MIT |
- Scrolling / long-page capture
- Blur / pixelate annotation
- OCR via
Windows.Media.Ocr— copy text from a snip - Persisted preferences (rebindable hotkeys, default save folder, widget position)
- Capture-history gallery
- Drag-and-drop the snip out to other apps (Slack, Teams, file explorer)
MIT — see LICENSE.