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
- 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.
- Check JobStatus for PrintJobStatus.Deleted/Completed/Error before calling Refresh and skip the refresh for terminal states.
- Wrap long-running queue monitoring in a try/catch that re-creates the PrintQueue connection (PrintServer.GetPrintQueue) when refresh fails repeatedly.
- 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
- Check JobStatus for Deleted/Completed/Error before each Refresh in polling loops.
- Re-enumerate queue jobs instead of refreshing long-lived PrintSystemJobInfo references.
- Refresh at most on job-status change events, not on tight timers, to shrink the delete race window.
- Verify print-server connectivity (queue online, not offline) before batch refreshes.
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
- ArgumentException.NonNegativeValue (Parameter 'squareScale')
- ArgumentException.PositiveValue (Parameter 'value')
- ArgumentException.PositiveValue (Parameter 'value')
- errMsg (dynamic: message of caught…
- getPage
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)