dotnet/wpf · error · Win32Exception
Win32Exception
Error message
Win32Exception
What it means
During font-cache initialization, Util obtains a device context for the desktop window via GetDC to read the system DPI (LOGPIXELSY). If GetDC returns IntPtr.Zero it throws Win32Exception, signaling the Win32 display/GDI subsystem failed to provide a DC.
Solutions
- Run the application in an interactive user session with an available desktop (not session 0).
- If running as a service/CI, ensure the process runs under a logged-in user account with a desktop, or use a headless-safe rendering path.
- Check GDI handle usage; fix handle leaks so GetDC can allocate.
- Delay/avoid font-cache-touching APIs until the app has a valid HWND/desktop association.
Example fix
// before (service context)
// FontCache utilization happens on startup -> Win32Exception
// after: run rendering work only after the service has an interactive session,
// or guard:
if (Environment.UserInteractive)
StartWpfFontDependentWork();
else
Log("WPF font APIs require an interactive desktop session"); Defensive patterns
Strategy: try-catch
Validate before calling
if (!Environment.UserInteractive)
throw new InvalidOperationException("WPF font APIs require an interactive desktop session."); Try / catch
try
{
StartFontDependentWork();
}
catch (Win32Exception ex)
{
Log($"GDI/desktop unavailable for font cache init: {ex.Message}");
// run in interactive session or defer work
} Prevention
- Do not run WPF rendering/font code in session 0 or headless services.
- Monitor and avoid GDI handle leaks.
- Initialize font-dependent work only after the process has a window/desktop association.
When it happens
Trigger: Util.GetSystemDPI (first DPI access) calling GetDC(desktopWnd) when no desktop window handle is available or GDI resources are exhausted, yielding a null DC.
Common situations: Running WPF in a session without an interactive desktop (e.g. a Windows service or session-0 context); running under a headless CI agent; GDI handle exhaustion; calling font APIs before the window station/desktop is attached.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- Win32Exception
- Win32Exception (unmanaged GetDC returned zero; Win32 error…
- ArgumentNullException
- InvalidOperationException
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/4696c3a8439c8c96.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontCacheUtil.cs:357
internal static int Dpi
{
get
{
if (!_dpiInitialized)
{
lock (_dpiLock)
{
if (!_dpiInitialized)
{
HandleRef desktopWnd = new HandleRef(null, IntPtr.Zero);
// Win32Exception will get the Win32 error code so we don't have to
IntPtr dc = MS.Win32.UnsafeNativeMethods.GetDC(desktopWnd);
// Detecting error case from unmanaged call, required by PREsharp to throw a Win32Exception
if (dc == IntPtr.Zero)
{
throw new Win32Exception();
}
try
{
_dpi = MS.Win32.UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, dc), NativeMethods.LOGPIXELSY);
_dpiInitialized = true;
}
finally
{
MS.Win32.UnsafeNativeMethods.ReleaseDC(desktopWnd, new HandleRef(null, dc));
}
}
}
}
return _dpi;
}
}
View on GitHub (pinned to 81131a70a4)