memstechtips/Winhance · error · Win32Exception

DISM {operation} failed with HRESULT 0x{hr:X8}

Error message

DISM {operation} failed with HRESULT 0x{hr:X8}

What it means

ThrowIfFailed wraps native DISM P/Invoke results: if the returned HRESULT hr is negative (high bit set), it throws System.ComponentModel.Win32Exception with that HRESULT as the native error code. This is the standard pattern for surfacing native DISM failures (Initialize, OpenSession, GetImageInfo, etc.) into managed exceptions.

Source

Thrown at src/Winhance.Core/Features/Common/Native/DismApi.cs:166

    // --- Helpers ---

    public static T[] MarshalArray<T>(IntPtr ptr, uint count) where T : struct
    {
        var result = new T[count];
        var structSize = Marshal.SizeOf<T>();
        for (uint i = 0; i < count; i++)
        {
            result[i] = Marshal.PtrToStructure<T>(ptr + (int)(i * structSize));
        }
        return result;
    }

    public static void ThrowIfFailed(int hr, string operation)
    {
        if (hr < 0)
        {
            throw new Win32Exception(hr, $"DISM {operation} failed with HRESULT 0x{hr:X8}");
        }
    }
}

View on GitHub (pinned to f23d554eb2)

Solutions

  1. Decode the HRESULT: 0x8007xxxx maps to Win32 GetLastError — look up the low 16 bits. 0x800F0xxx and 0xC1420xxx are CBS/DISM-specific.
  2. Verify the image path exists and is a valid WIM before opening a session (use DismGetImageInfo to probe).
  3. Run elevated — most DISM servicing calls require administrator privileges.
  4. Ensure no other DISM session or dism.exe process is servicing the same image.
  5. On Windows, run `sfc /scannow` and `DISM /Online /Cleanup-Image /RestoreHealth` to repair the DISM/CBS stack if HRESULTs are consistently corrupt-state.

Example fix

// before
public static void ThrowIfFailed(int hr, string operation)
{
    if (hr < 0)
        throw new Win32Exception(hr, $"DISM {operation} failed with HRESULT 0x{hr:X8}");
}

// after: translate known DISM HRESULTs into actionable messages
public static void ThrowIfFailed(int hr, string operation)
{
    if (hr >= 0) return;
    var msg = hr switch
    {
        unchecked((int)0x80070002) => $"DISM {operation}: file not found (0x{hr:X8}). Check the image path.",
        unchecked((int)0x80070005) => $"DISM {operation}: access denied (0x{hr:X8}). Run as administrator.",
        unchecked((int)0xC1420115) => $"DISM {operation}: image not mounted/available (0x{hr:X8}).",
        _ => $"DISM {operation} failed with HRESULT 0x{hr:X8}"
    };
    throw new Win32Exception(hr, msg);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the image path exists and is a recognizable WIM before opening a DISM session.
bool IsImageOpenable(string path) => _fileSystemService.FileExists(path);
// Then call DismApi.DismGetImageInfo to confirm it is a valid WIM before DismOpenSession.

Try / catch

catch (System.ComponentModel.Win32Exception ex) when (ex.Message.Contains("DISM") && ex.Message.Contains("HRESULT"))
{
    // Decode the NativeErrorCode; map 0x80070002 -> file-not-found, 0x80070005 -> needs elevation, etc.
}

Prevention

When it happens

Trigger: Any DismApi call that returns an HRESULT passes through ThrowIfFailed: DismInitialize, DismOpenSession, DismGetImageInfo, DismCloseSession, DismShutdown. A negative HRESULT means the DISM servicing engine rejected the call — e.g. 0x80070002 (file not found), 0x80070005 (access denied), 0xC1420115 (image not mounted), 0x800F0906 (source missing).

Common situations: The image path passed to DismOpenSession does not exist or is not a valid WIM/VHD. The process is not elevated. The image is already being serviced by another DISM session. The native DISM binaries (dismapi.dll) are missing or wrong version for the OS. A mounted image was unmounted externally.

Related errors


AI-assisted analysis of memstechtips/Winhance@f23d554eb2 (2026-08-13). Data as JSON: /api/errors/da91178486de14e4. Report an issue: GitHub.