Skip to content

GetWindowDC(0) called unconditionally in __init__ prevents monitor-only usage #509

@mxschmitt

Description

@mxschmitt

Problem

MSSImplWindows.__init__() calls GetWindowDC(0) (line 207 of mss/windows/gdi.py) unconditionally during construction, even when the caller only needs monitor geometry (sct.monitors) and never calls grab().

GetWindowDC(0) can fail with WinError 5: Access is denied when:

  • The desktop is temporarily inaccessible (locked screen, UAC prompt, RDP disconnect)
  • GDI handles were leaked by a previous session

This means even with mss.MSS() as sct: sct.monitors fails in these scenarios, despite monitors() only needing EnumDisplayMonitors(0, ...) + GetMonitorInfoW which do not require a desktop device context.

Reproduction

import mss
# This fails with ScreenShotError("GetWindowDC: Access is denied")
# when the desktop DC is unavailable, even though we only read monitors:
with mss.MSS() as sct:
    print(sct.monitors)

Suggestion

Defer GetWindowDC(0) and CreateCompatibleDC to grab() (or a lazy init on first grab) instead of acquiring them in __init__. This would allow monitor enumeration to work regardless of desktop DC availability.

Alternatively, provide a lightweight API for monitor enumeration that doesn't construct the full capture pipeline.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions