HandyOrg/HandyControl · critical

StatusException(status)

Error message

StatusException(status)

What it means

During lazy GDI+ startup in InteropMethods, GdiplusStartup returned a non-Ok status and StatusException is thrown. This means the GDI+ library could not be initialized for the process — no GDI+ drawing/codec APIs will work afterward.

Solutions

  1. Check the exact status code in the exception (NotInitialized/OutOfMemory/etc.) to pinpoint the failure.
  2. Verify gdiplus.dll is present and healthy on the machine (sfc /scannow).
  3. Avoid calling GDI+ APIs in non-default app domains or before the runtime is fully loaded; force initialization early in Main.
  4. If running in a restricted environment, switch to a non-GDI+ imaging library (e.g. SkiaSharp, WIC).
  5. Ensure StartupInput/InitToken handling matches the GDI+ version in use.

Example fix

// before
var status = GdiplusStartup(out InitToken, ref input, out _);
if (status != Ok)
{
    throw StatusException(status);
}
// after
var status = GdiplusStartup(out InitToken, ref input, out _);
if (status != Ok)
{
    throw StatusException(status, $"GDI+ startup failed (status={status}); ensure gdiplus.dll is available and the app domain supports GDI+");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!InteropMethods.Gdip.ApplicationStarted)
{
    try { InteropMethods.Gdip.EnsureGdiplusInitialized(); }
    catch (StatusException ex) { logger.Fatal($"GDI+ init failed: {ex.Status}"); throw; }
}

Type guard

bool CanUseGdiplus() => Environment.OSVersion.Platform == PlatformID.Win32NT && InteropMethods.Gdip.ApplicationStarted;

Try / catch

try
{
    InitializeGdiplusDependentFeature();
}
catch (StatusException ex)
{
    logger.Fatal($"GDI+ startup failed (status {ex.Status}); disabling imaging features.");
    featureEnabled = false;
}

Prevention

When it happens

Trigger: First GDI+ usage in the app domain triggers EnsureGdiplusInitialized; GdiplusStartup fails with statuses like NotImplemented (rare platforms) or OutOfMemory, or startup is attempted in an unsupported app domain hosting scenario.

Common situations: Unusual hosting environments (unit-test app domains, plugins, server environments where GDI+ is restricted), corrupted GDI+ install, or platform (Wine/trimmed Windows) lacking GDI+ support.

Related errors


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

Appendix: source

Thrown at src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs:590

        private readonly struct StartupOutput
        {
            private readonly IntPtr hook;

            private readonly IntPtr unhook;
        }

        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
        [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals")]
        private static void Initialize()
        {
            var input = StartupInput.GetDefault();

            var status = GdiplusStartup(out InitToken, ref input, out _);

            if (status != Ok)
            {
                throw StatusException(status);
            }

            var currentDomain = AppDomain.CurrentDomain;
            currentDomain.ProcessExit += OnProcessExit;

            if (!currentDomain.IsDefaultAppDomain())
            {
                currentDomain.DomainUnload += OnProcessExit;
            }
        }

        [PrePrepareMethod]
        [ResourceExposure(ResourceScope.AppDomain)]
        [ResourceConsumption(ResourceScope.AppDomain)]
        private static void OnProcessExit(object sender, EventArgs e) => Shutdown();

        [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")]
        [ResourceExposure(ResourceScope.AppDomain)]

View on GitHub (pinned to 2c0875ebd6)