dotnet/wpf · error · PrintQueueException

PrintSystemException.PrintQueue.Resume

Error message

PrintSystemException.PrintQueue.Resume

What it means

PrintQueue.Resume converts a Win32 SetPrinter(PRINTER_CONTROL_RESUME) failure into a PrintSystemException tagged 'PrintSystemException.PrintQueue.Resume'. Resuming asks the spooler to restart job scheduling on a paused queue; the HResult holds the native error.

Solutions

  1. Run with Manage Printer permission on the queue.
  2. Check queue state first (queue.IsPaused or queue.QueueStatus) and skip Resume when not paused.
  3. Verify the printer still exists and is reachable on the print server.
  4. Retry once after checking the spooler service if the error indicates a transient spooler state.

Example fix

// before
queue.Resume();
// after
if ((queue.QueueStatus & PrintQueueStatus.Paused) != 0)
{
    try { queue.Resume(); }
    catch (PrintSystemException ex) { throw new InvalidOperationException($"Failed to resume '{queue.FullName}': 0x{ex.HResult:X8}", ex); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ((queue.QueueStatus & PrintQueueStatus.Paused) == 0) throw new InvalidOperationException("Queue is not paused; Resume not applicable");

Try / catch

try { queue.Resume(); }
catch (PrintSystemException ex) { throw new InvalidOperationException($"Resume failed for '{queue.FullName}': 0x{ex.HResult:X8}", ex); }

Prevention

When it happens

Trigger: Calling queue.Resume() when the spooler rejects SetPrinter with PRINTER_CONTROL_RESUME — access denied, queue not actually paused, printer renamed/deleted, or unreachable remote server.

Common situations: Resuming a queue another admin already resumed or deleted; non-admin user resuming a shared corporate printer; transient network failure to the print server.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PrintQueue.cpp:1369

    Return Value
        None
--*/
void
PrintQueue::
Resume(
    void
    )
{
    VerifyAccess();

    try
    {
        printerThunkHandler->ThunkSetPrinter(PRINTER_CONTROL_RESUME);
    }
    catch (InternalPrintSystemException^ internalException)
    {
        throw CreatePrintQueueException(internalException->HResult,
                                        "PrintSystemException.PrintQueue.Resume");
    }
}

PrintSystemJobInfo^
PrintQueue::
AddJob(
    void
    )
{
    VerifyAccess();

    // We need to pass down a print ticket so that the job ID will be available
    // immediately.  Since the caller did not specify a print ticket, we will use
    // the user/default print ticket for this print queue.
    PrintTicket^ printTicket = UserPrintTicket;
    if(printTicket == nullptr)
    {

View on GitHub (pinned to 81131a70a4)