{"record":{"id":"aa72425b1ec287c2","repo":"dotnet/wpf","slug":"win32exception-unmanaged-getdc-returned-zero-win32-error","errorCode":null,"errorMessage":"Win32Exception (unmanaged GetDC returned zero; Win32 error code carried by Win32Exception)","messagePattern":"Win32Exception \\(unmanaged GetDC returned zero; Win32 error code carried by Win32Exception\\)","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs","lineNumber":1142,"sourceCode":"        /// </summary>\n        /// <remarks>\n        /// Should be called before reading _dpiScaleX and _dpiScaleY\n        /// </remarks>\n        internal static DpiScale EnsureDpiScale()\n        {\n            if (_setDpi)\n            {\n                _setDpi = false;\n                int dpiX, dpiY;\n                HandleRef desktopWnd = new HandleRef(null, IntPtr.Zero);\n\n                // Win32Exception will get the Win32 error code so we don't have to\n                IntPtr dc = UnsafeNativeMethods.GetDC(desktopWnd);\n\n                // Detecting error case from unmanaged call, required by PREsharp to throw a Win32Exception\n                if (dc == IntPtr.Zero)\n                {\n                    throw new Win32Exception();\n                }\n\n                try\n                {\n                    dpiX = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSX);\n                    dpiY = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSY);\n                    _dpiScaleX = (double)dpiX / DpiUtil.DefaultPixelsPerInch;\n                    _dpiScaleY = (double)dpiY / DpiUtil.DefaultPixelsPerInch;\n                }\n                finally\n                {\n                    UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));\n                }\n            }\n            return new DpiScale(_dpiScaleX, _dpiScaleY);\n        }\n\n        /// <summary>","sourceCodeStart":1124,"sourceCodeEnd":1160,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs#L1124-L1160","documentation":"Win32's GetDC returned a null device-context handle while UIElement.EnsureDpiScale queried the desktop DC for LOGPIXELSX/LOGPIXELSY. The library cannot determine system DPI, so it surfaces the raw Win32 error via Win32Exception. This indicates the Win32/GDI environment could not provide a DC for the desktop window.","triggerScenarios":"Calling WPF APIs that trigger DPI detection (element measure/arrange, window creation, DPI-changed handling) when GetDC(desktopWnd) returns IntPtr.Zero, e.g. in a non-interactive session or after GDI handle exhaustion.","commonSituations":"Running a WPF app in a Windows Service (Session 0) with no interactive desktop; leaking GDI handles until the process hits the 10,000 GDI-object cap; terminal-service/headless environments; heavily loaded systems low on system resources.","solutions":["Fix the GDI handle leak (e.g. always ReleaseDC / dispose Graphics objects) and verify GDI object count in Task Manager","Do not create WPF UI in a non-interactive session (Session 0); run as an interactive user or use session-0-safe alternatives","Retry after freeing system resources / rebooting a degraded session","Capture Win32Exception.ErrorCode/NativeErrorCode to identify the exact Win32 failure"],"exampleFix":"// before\nIntPtr dc = UnsafeNativeMethods.GetDC(desktopWnd);\ntry { ... } finally { UnsafeNativeMethods.ReleaseDC(desktopWnd, dc); }\n// after\nIntPtr dc = UnsafeNativeMethods.GetDC(desktopWnd);\nif (dc == IntPtr.Zero) { log.Error($\"GetDC failed: {Kernel32.GetLastError()}\"); return; }\ntry { ... } finally { UnsafeNativeMethods.ReleaseDC(desktopWnd, dc); }","handlingStrategy":"try-catch","validationCode":"// Check GDI headroom and interactive session before UI work\nbool canQueryDpi = Environment.UserInteractive && GetGdiHandlesInUse(Process.GetCurrentProcess()) < 9000;","typeGuard":null,"tryCatchPattern":"try { element.UpdateLayout(); }\ncatch (Win32Exception ex) { log.Error($\"Win32 error {ex.NativeErrorCode} during DPI detection\", ex); /* degrade gracefully */ }","preventionTips":["Always pair GetDC with ReleaseDC and dispose GDI wrappers (Graphics, Pen, Brush)","Monitor the process GDI object count (Task Manager > Details > GDI Objects)","Never build WPF visual trees inside Session 0 / Windows services"],"tags":["wpf","win32","gdi","dpi"],"backgroundTag":"win32-getdc-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}