dotnet/wpf · error · PrintJobException

PrintSystemException.PrintSystemJobInfo.Refresh

Error message

PrintSystemException.PrintSystemJobInfo.Refresh

What it means

PrintSystemJobInfo.Refresh threw CreatePrintJobException with this message when the native refresh of the print job's properties failed against the spooler. In the source path, Refresh succeeds only while the underlying spool job still exists; when the job handle/lookup fails (typically because the job no longer exists), the native code falls into the else branch and throws this exception carrying the inner COM exception's HResult. It indicates the cached PrintSystemJobInfo no longer maps to a live spooler job.

Solutions

  1. Catch PrintSystemException (or the derived print exception) around Refresh and treat it as 'job no longer exists': re-enumerate via PrintQueue.GetPrintJobInfoCollection instead of refreshing the stale object.
  2. Check JobStatus for PrintJobStatus.Deleted/Completed/Error before calling Refresh and skip the refresh for terminal states.
  3. Wrap long-running queue monitoring in a try/catch that re-creates the PrintQueue connection (PrintServer.GetPrintQueue) when refresh fails repeatedly.
  4. If the spooler was temporarily unavailable, retry Refresh after a short delay and verify queue connectivity (PrintQueue.IsOffline / queue status).

Example fix

// before
job.Refresh();
Console.WriteLine(job.JobStatus);
// after
try
{
    if ((job.JobStatus & PrintJobStatus.Deleted) == 0 &&
        (job.JobStatus & PrintJobStatus.Completed) == 0)
    {
        job.Refresh();
    }
}
catch (PrintSystemException ex)
{
    // job vanished from the spooler; re-enumerate
    var jobs = printQueue.GetPrintJobInfoCollection();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before refresh
if ((job.JobStatus & PrintJobStatus.Deleted) != 0 ||
    (job.JobStatus & PrintJobStatus.Completed) != 0 ||
    (job.JobStatus & PrintJobStatus.Error) != 0)
    return; // skip refresh for terminal states

Try / catch

try { job.Refresh(); }
catch (PrintSystemException ex)
{
    // job no longer exists on the spooler; re-enumerate
    jobs = printQueue.GetPrintJobInfoCollection();
    job = jobs.FirstOrDefault(j => j.Name == expectedName);
}

Prevention

When it happens

Trigger: Calling PrintSystemJobInfo.Refresh() after the job has been deleted from the queue, finished printing and been purged by the spooler, or when the underlying HResult from the spooler (PRNJOB lookup) indicates the job is gone; also when the print queue connection is broken mid-refresh.

Common situations: Monitoring a print queue in a loop and the job completes/is cancelled between property reads; user cancels the job from the printer UI while your app holds a PrintSystemJobInfo; remote print server goes offline; a race between job deletion notification and the next Refresh call.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PrintSystemJobInfo.cpp:1105

    void
    )
{
    VerifyAccess();

    try
    {
        PopulateJobProperties(refreshPropertiesFilter);
    }
    catch (InternalPrintSystemException^ internalException)
    {
        if (IsErrorInvalidParameter(internalException->HResult))
        {
            get_InternalPropertiesCollection("Status")->GetProperty("Status")->IsInternallyInitialized = true;
            this->JobStatusSecondary = static_cast<Int32>(PrintJobStatus::Deleted);
        }
        else
        {
            throw CreatePrintJobException(internalException->HResult,
                                          "PrintSystemException.PrintSystemJobInfo.Refresh");
        }
    }
}

__declspec(noinline)
bool
PrintSystemJobInfo::
IsErrorInvalidParameter(
    int hResult
    )
{
    return PrinterHResult::HResultCode(hResult) == ERROR_INVALID_PARAMETER;
}


PrintProperty^
PrintSystemJobInfo::

View on GitHub (pinned to 81131a70a4)