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
Problem
MSSImplWindows.__init__()callsGetWindowDC(0)(line 207 ofmss/windows/gdi.py) unconditionally during construction, even when the caller only needs monitor geometry (sct.monitors) and never callsgrab().GetWindowDC(0)can fail withWinError 5: Access is deniedwhen:This means even
with mss.MSS() as sct: sct.monitorsfails in these scenarios, despitemonitors()only needingEnumDisplayMonitors(0, ...)+GetMonitorInfoWwhich do not require a desktop device context.Reproduction
Suggestion
Defer
GetWindowDC(0)andCreateCompatibleDCtograb()(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