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

  1. Run the application in an interactive user session with an available desktop (not session 0).
  2. 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.
  3. Check GDI handle usage; fix handle leaks so GetDC can allocate.
  4. 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

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


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)