dotnet/wpf · error · PrintJobException

PrintSystemException.PrintSystemJobInfo.ReportJobProgress

Error message

PrintSystemException.PrintSystemJobInfo.ReportJobProgress

What it means

Raised from ReportJobProgress when the internal call to ThunkReportJobProgress (telling the spooler the job is progressing/producing) fails with an InternalPrintSystemException. The HRESULT is wrapped into a PrintSystemException with key PrintSystemException.PrintSystemJobInfo.ReportJobProgress. It indicates the progress report to the spooler could not be delivered for the given jobIdentifier.

Solutions

  1. Check that the job is still active (JobStatus) before reporting progress and skip the report if it is not
  2. Catch PrintSystemException in job progress event handlers so a failed report does not crash printing
  3. Ensure the jobIdentifier corresponds to a job created on the same PrintQueue/server connection
  4. Confirm the Print Spooler service is healthy if the error recurs across jobs

Example fix

// before
jobInfo.ReportJobProgress(...); // may throw
// after
if ((jobInfo.JobStatus & PrintJobStatus.Completed) == 0)
{ try { jobInfo.ReportJobProgress(...); } catch (PrintSystemException) { /* skip stale progress report */ } }
Defensive patterns

Strategy: try-catch

Validate before calling

if (jobInfo == null) return;
if ((jobInfo.JobStatus & (PrintJobStatus.Completed | PrintJobStatus.Deleted | PrintJobStatus.Error)) != 0) return;

Type guard

static bool IsJobActive(PrintSystemJobInfo j) => j != null && (j.JobStatus & (PrintJobStatus.Completed | PrintJobStatus.Deleted)) == 0;

Try / catch

try { ReportJobProgress(...); }
catch (PrintSystemException ex) { Log("progress report failed: 0x" + ex.HResult.ToString("X")); }

Prevention

When it happens

Trigger: Calling the internal ReportJobProgress path (used during XPS/print pipeline progress reporting, e.g. from PrintSystemJobInfo progress events) with an invalid or completed job id, or when the spooler rejects the JobOperation.JobProduction report.

Common situations: Job finished/deleted before the progress event fired; spooler service unavailable; progress reporting wired to a job that came from a different PrintServer/queue instance.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/7ddeeb9863633a17. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PremiumPrintStream.cpp:558

    // last commit operation and get reset to 0 as the data is commited.
    // If interleaving is not enabled we write the data when the stream is closed,
    // in which case bytesToCommit should be the total length of the stream.
    //
    if (e->Action == PackagingAction::FixedPageCompleted &&
        commitStreamDataOnClose == false)
    {
        CommitDataToPrinter();
    }

    try
    {
        printerThunkHandler->ThunkReportJobProgress(jobIdentifier,
                                                        JobOperation::JobProduction,
                                                        e->Action);
    }
    catch(InternalPrintSystemException^ internalException)
    {
        throw PrintSystemJobInfo::CreatePrintJobException(internalException->HResult,
                                      "PrintSystemException.PrintSystemJobInfo.ReportJobProgress");
    }
}

void
PrintQueueStream::
CommitDataToPrinter(
    void
    )
{
    Int64 commited  = 0;
    try
    {
        //
        // The the spool file position to the last position up to which
        // the data was commited. Spooler will move the file pointer to the new position.
        // If we don't do this, the position will be moved by the Spooler beyond the end of the file.
        //

View on GitHub (pinned to 81131a70a4)