home / skills / openclaw / skills / win-screenshot

This skill captures screenshots on Windows using built-in tools for quick full screen, region, or window captures.

npx playbooks add skill openclaw/skills --skill win-screenshot

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
5.6 KB
---
name: win-screenshot
description: Capture screenshots on Windows (full screen, region, or specific window).
metadata:
  {
    "openclaw":
      {
        "emoji": "📸",
        "os": ["win32"],
      },
  }
---

# win-screenshot

Capture screenshots on Windows using PowerShell and .NET System.Drawing.
No external dependencies — uses built-in Windows APIs.

Pair with OpenClaw's `image` tool to analyze captured screenshots.

## Full Screen Capture

```powershell
powershell.exe -NoProfile -Command "
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
$bmp = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size)
$bmp.Save('OUTPUT_PATH', [System.Drawing.Imaging.ImageFormat]::Png)
$g.Dispose(); $bmp.Dispose()
Write-Host 'Saved to OUTPUT_PATH'
"
```

Replace `OUTPUT_PATH` with the desired file path (e.g., `$env:TEMP\screenshot.png`).

## Region Capture

Capture a specific rectangular area (x, y, width, height):

```powershell
powershell.exe -NoProfile -Command "
Add-Type -AssemblyName System.Drawing
$bmp = New-Object System.Drawing.Bitmap(WIDTH, HEIGHT)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.CopyFromScreen(X, Y, 0, 0, [System.Drawing.Size]::new(WIDTH, HEIGHT))
$bmp.Save('OUTPUT_PATH', [System.Drawing.Imaging.ImageFormat]::Png)
$g.Dispose(); $bmp.Dispose()
"
```

Replace `X`, `Y`, `WIDTH`, `HEIGHT` with pixel coordinates.

## Multi-Monitor (All Screens)

```powershell
powershell.exe -NoProfile -Command "
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$bounds = [System.Windows.Forms.SystemInformation]::VirtualScreen
$bmp = New-Object System.Drawing.Bitmap($bounds.Width, $bounds.Height)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size)
$bmp.Save('OUTPUT_PATH', [System.Drawing.Imaging.ImageFormat]::Png)
$g.Dispose(); $bmp.Dispose()
"
```

## List Visible Windows

List all visible windows with titles and dimensions (useful before targeted capture):

```powershell
powershell.exe -NoProfile -Command "
Add-Type @'
using System;
using System.Runtime.InteropServices;
using System.Text;
public class WinAPI {
    [DllImport(\"user32.dll\")] public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
    [DllImport(\"user32.dll\")] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    [DllImport(\"user32.dll\")] public static extern bool IsWindowVisible(IntPtr hWnd);
    [DllImport(\"user32.dll\")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
    [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
}
'@
[WinAPI]::EnumWindows({
    param(`$hWnd, `$lParam)
    if ([WinAPI]::IsWindowVisible(`$hWnd)) {
        `$sb = New-Object System.Text.StringBuilder(256)
        [WinAPI]::GetWindowText(`$hWnd, `$sb, 256) | Out-Null
        `$title = `$sb.ToString()
        if (`$title.Length -gt 0) {
            `$rect = New-Object WinAPI+RECT
            [WinAPI]::GetWindowRect(`$hWnd, [ref]`$rect) | Out-Null
            `$w = `$rect.Right - `$rect.Left; `$h = `$rect.Bottom - `$rect.Top
            Write-Host \"`$title | `$(`$rect.Left),`$(`$rect.Top) `${w}x`${h}\"
        }
    }
    return `$true
}, [IntPtr]::Zero) | Out-Null
"
```

## Capture Specific Window by Title

Use region capture with coordinates from the window list:

```powershell
powershell.exe -NoProfile -Command "
Add-Type -AssemblyName System.Drawing
Add-Type @'
using System;
using System.Runtime.InteropServices;
using System.Text;
public class WinFind {
    [DllImport(\"user32.dll\")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport(\"user32.dll\")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
}
'@
`$hWnd = [WinFind]::FindWindow(`$null, 'WINDOW_TITLE')
if (`$hWnd -eq [IntPtr]::Zero) { Write-Host 'Window not found'; exit 1 }
`$rect = New-Object WinFind+RECT
[WinFind]::GetWindowRect(`$hWnd, [ref]`$rect) | Out-Null
`$w = `$rect.Right - `$rect.Left; `$h = `$rect.Bottom - `$rect.Top
`$bmp = New-Object System.Drawing.Bitmap(`$w, `$h)
`$g = [System.Drawing.Graphics]::FromImage(`$bmp)
`$g.CopyFromScreen(`$rect.Left, `$rect.Top, 0, 0, [System.Drawing.Size]::new(`$w, `$h))
`$bmp.Save('OUTPUT_PATH', [System.Drawing.Imaging.ImageFormat]::Png)
`$g.Dispose(); `$bmp.Dispose()
Write-Host \"Captured window: `${w}x`${h}\"
"
```

Replace `WINDOW_TITLE` with the exact window title from the window list.

## Recommended Workflow

1. **List windows** to find the target
2. **Capture** (full screen, region, or window)
3. Use OpenClaw's **`image` tool** to analyze the screenshot

```
win-screenshot (capture) → image tool (analyze) → agent acts on result
```

## Notes

- Works on Windows 10/11 with PowerShell 5.1+.
- No external dependencies — uses built-in .NET Framework assemblies.
- Output format: PNG (lossless). Change `ImageFormat::Png` to `Jpeg` for smaller files.
- For WSL: call `powershell.exe` from within WSL; save to a Windows-accessible path.
- DPI scaling: captured resolution matches the actual screen pixels.
- Window capture uses screen coordinates — it captures what's visible (may include overlapping windows).
- Default save location suggestion: `$env:TEMP\pcclaw-screenshot.png`.

Overview

This skill captures screenshots on Windows using built-in PowerShell and .NET APIs. It supports full-screen, multi-monitor, arbitrary region, and specific-window captures without external dependencies. Outputs are PNG by default for lossless images and work on Windows 10/11 with PowerShell 5.1+.

How this skill works

The skill runs PowerShell commands that load System.Drawing and System.Windows.Forms or call user32.dll functions to enumerate windows and get window rectangles. It creates a Bitmap, uses Graphics.CopyFromScreen to copy pixels for the requested area, saves the image to a file, and disposes of resources. For window-targeted captures it first lists visible windows or finds a window by title, then captures the window rectangle coordinates.

When to use it

  • Capture the entire desktop or multiple monitors for documentation or debugging.
  • Grab a specific rectangular region for focused UI snapshots.
  • Capture a visible application window by title for automated testing or reporting.
  • Use from WSL by invoking powershell.exe to save images to a Windows-accessible path.
  • Produce lossless PNG screenshots for image analysis pipelines.

Best practices

  • List visible windows first to get exact window titles and coordinates before targeting captures.
  • Save to a stable, writable path (e.g., %TEMP%) and include timestamps in filenames to avoid overwriting.
  • Be aware of overlapping windows—window captures use screen pixels and may include occlusions.
  • If file size matters, switch ImageFormat to Jpeg but keep in mind compression artifacts for analysis.
  • Run commands with NoProfile to avoid side effects from user PowerShell profiles.

Example use cases

  • Automate UI snapshot collection during regression tests across multiple monitors.
  • Capture an application window to attach to a bug report with exact on-screen state.
  • Combine with an image-analysis tool to detect UI changes or visual regressions.
  • Run from WSL scripts that need Windows screenshots and save to a shared path.
  • Create time-lapse captures of desktop state by invoking the capture command on a schedule.

FAQ

Does this require installing any libraries?

No. It uses built-in .NET Framework assemblies and Windows APIs, so no external dependencies are required.

Will it capture off-screen or minimized windows?

No. It captures pixels as they appear on screen. Minimized or fully off-screen windows will not render; use the window list to confirm visibility.

How do I capture a specific window?

First run the window-list command to get the exact title and coordinates, then use the window-capture command with that title or coordinates to save the region.