HandyOrg/HandyControl · critical · Exception

Unable to initialize GDI+

Error message

Unable to initialize GDI+

What it means

SafeGdiplusStartupToken.Startup calls GdiplusStartup; if the returned Status is not Ok the token is disposed and a bare Exception('Unable to initialize GDI+') is thrown, since all GDI+ drawing depends on a successful startup token.

Solutions

  1. Verify gdiplus.dll is present and a supported version on the machine
  2. Check the returned startupOutput.Status value for the specific GDI+ failure reason
  3. Ensure the app targets a supported Windows version / install the platform update
  4. Catch the exception and disable GDI+-dependent features gracefully

Example fix

// before
var token = SafeGdiplusStartupToken.Startup(); // throws bare Exception on old systems
// after
SafeGdiplusStartupToken token = null;
try { token = SafeGdiplusStartupToken.Startup(); }
catch (Exception) { /* fallback: skip GDI+ rendering */ }
Defensive patterns

Strategy: try-catch

Validate before calling

static bool GdiPlusAvailable() =>
    NativeMethods.LoadLibrary("gdiplus.dll") != IntPtr.Zero;

Type guard

static bool IsGdiplusTokenValid(SafeGdiplusStartupToken t) => t != null && !t.IsInvalid;

Try / catch

try { token = SafeGdiplusStartupToken.Startup(); }
catch (Exception ex) { Log.Error("GDI+ startup failed", ex); DisableRenderingFeatures(); }

Prevention

When it happens

Trigger: Calling SafeGdiplusStartupToken.Startup when GdiplusStartup returns a non-Ok Status — e.g. GdiplusNotInitialized, OutOfMemory, or UnsupportedGdiplusVersion — typically when gdiplus.dll is missing or too old.

Common situations: Running on stripped-down/Server Core Windows installs without GDI+, corrupted system libraries, or unusual remote-session environments.

Related errors


AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14). Data as JSON: /api/errors/8f2981f4c18bd976. Report an issue: GitHub.

Appendix: source

Thrown at src/Shared/Microsoft.Windows.Shell/Standard/SafeGdiplusStartupToken.cs:35

        Status status = NativeMethods.GdiplusShutdown(this.handle);
        return status == Status.Ok;
    }

    [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
    [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
    public static SafeGdiplusStartupToken Startup()
    {
        SafeGdiplusStartupToken safeGdiplusStartupToken = new SafeGdiplusStartupToken();
        IntPtr handle;
        StartupOutput startupOutput;
        if (NativeMethods.GdiplusStartup(out handle, new StartupInput(), out startupOutput) == Status.Ok)
        {
            safeGdiplusStartupToken.handle = handle;
            return safeGdiplusStartupToken;
        }
        safeGdiplusStartupToken.Dispose();
        throw new Exception("Unable to initialize GDI+");
    }
}

View on GitHub (pinned to 2c0875ebd6)