memstechtips/Winhance · error · Exception

oscdimg.exe failed with exit code: {exitCode}

Error message

oscdimg.exe failed with exit code: {exitCode}

What it means

oscdimg.exe (the Windows ADK / Deployment Tools ISO authoring tool) exited with a non-zero code while building the ISO. oscdimg is the actual tool invoked with -m -o -u2 -udfver102 and the dual bootdata segment; a non-zero exit means image authoring failed. The thrown Exception carries only the exit code — oscdimg's textual error was streamed to progress output, not captured in the message.

Source

Thrown at src/Winhance.Infrastructure/Features/AdvancedTools/Services/IsoService.cs:333

                _fileSystemService.CreateDirectory(outputDir);

            if (_fileSystemService.FileExists(outputPath))
            {
                _fileSystemService.DeleteFile(outputPath);
                _logService.LogInformation("Removed existing ISO file");
            }

            var arguments = $"-m -o -u2 -udfver102 -bootdata:2#p0,e,b\"{etfsbootPath}\"#pEF,e,b\"{efisysPath}\" \"{workingDirectory}\" \"{outputPath}\"";

            progress?.Report(new TaskProgressDetail
            {
                TerminalOutput = "Running oscdimg.exe...\nThis may take several minutes..."
            });

            var (exitCode, _) = await _dismProcessRunner.RunProcessWithProgressAsync(oscdimgPath, arguments, progress, cancellationToken).ConfigureAwait(false);
            if (exitCode != 0)
            {
                throw new Exception($"oscdimg.exe failed with exit code: {exitCode}");
            }

            // Verify ISO was created
            if (!_fileSystemService.FileExists(outputPath))
            {
                _logService.LogError("ISO file was not created");
                return false;
            }

            var isoFileSize = _fileSystemService.GetFileSize(outputPath);
            _logService.LogInformation($"ISO created successfully: {outputPath} ({isoFileSize:N0} bytes)");

            progress?.Report(new TaskProgressDetail
            {
                StatusText = _localization.GetString("Progress_IsoCreatedSuccess"),
                TerminalOutput = $"Location: {outputPath}\nSize: {isoFileSize / (1024 * 1024):F2} MB"
            });

View on GitHub (pinned to f23d554eb2)

Solutions

  1. Read the TerminalOutput lines captured during the run (shown in progress) — oscdimg prints the human-readable reason immediately before exiting.
  2. Run the same oscdimg command line manually in an elevated command prompt to see the exact error and exit code.
  3. Free space and write permissions on the output drive; close any process holding files in the working directory.
  4. Reinstall/repair ADK Deployment Tools so oscdimg.exe matches the Windows build, or switch to the lightweight Microsoft.OSCDIMG winget package.
  5. Add the oscdimg exit code into the thrown message so failures are self-describing (see exampleFix).

Example fix

// before
if (exitCode != 0)
    throw new Exception($"oscdimg.exe failed with exit code: {exitCode}");

// after: capture stderr/stdout so the exception carries oscdimg's own reason
var (exitCode, output) = await _dismProcessRunner.RunProcessWithProgressAsync(oscdimgPath, arguments, progress, cancellationToken).ConfigureAwait(false);
if (exitCode != 0)
    throw new Exception($"oscdimg.exe failed with exit code {exitCode}. Output: {output}");
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify oscdimg is present and the working tree is consistent before invoking it.
bool CanRunOscdimg(string oscdimgPath, string workingDirectory)
    => _fileSystemService.FileExists(oscdimgPath) && _fileSystemService.DirectoryExists(workingDirectory);

Try / catch

catch (Exception ex) when (ex.Message.Contains("oscdimg.exe failed"))
{
    // Parse the exit code from the message; surface the TerminalOutput lines captured during the run
    // (oscdimg's own text) to the user. Offer to retry after freeing handles / freeing disk space.
}

Prevention

When it happens

Trigger: RunProcessWithProgressAsync returned exitCode != 0 from oscdimg.exe. Common oscdimg failure codes: 1 = invalid argument/path, 2 = cannot open source directory, 5 = access denied, or non-zero from a source directory containing a file locked by another process. Also thrown if oscdimg is a stub/wrong version that exits non-zero.

Common situations: The working directory path contains characters oscdimg mishandles. A file inside the working directory is locked. The output path is on a read-only or full drive. oscdimg.exe present is from a mismatched/older ADK that does not support the dual-bootdata syntax. Antivirus blocks oscdimg writing the ISO.

Related errors


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