dotnet/wpf · error · PrintQueueException

PrintConfig.Provider.PT2DevModeFail

PrintConfig.Provider.PT2DevModeFail

Error message

PrintConfig.Provider.PT2DevModeFail

What it means

PTProvider.ConvertPrintTicketToDevMode failed to convert a PrintTicket into a Win32 DEVMODE structure via the print driver's native PT/PM conversion APIs. The provider wraps the native HRESULT in a PrintQueueException with code 'PrintConfig.Provider.PT2DevModeFail'. This usually means the ticket content is malformed or the driver rejected an option value.

Solutions

  1. Inspect errorMsg/_deviceName in the exception and validate the PrintTicket XML against the Print Schema before conversion.
  2. Rebuild the PrintTicket from a fresh PrintQueue.DefaultPrintTicket or ticket XML from a known-good source instead of a stale/hand-edited one.
  3. Verify the target driver is installed and functional (test printing from the OS); update or reinstall the printer driver.
  4. Catch PrintQueueException and fall back to queue defaults.

Example fix

// before
var devMode = ticket.GetXmlStream(); // hand-edited XML passed to conversion
// after
var ticket = new PrintTicket(queue.GetPrintCapabilities().... ); // build from validated queue capabilities
using var xml = ticket.GetXmlStream(); // well-formed ticket generated by the API
Defensive patterns

Strategy: try-catch

Validate before calling

if (ticket == null) throw new ArgumentNullException(nameof(ticket));
using var xml = ticket.GetXmlStream();
if (xml == null || xml.Length == 0) throw new InvalidOperationException("PrintTicket XML is empty");

Try / catch

try
{
    queue.GetPrintCapabilities(ticket);
}
catch (PrintQueueException ex) when (ex.Message.Contains("PT2DevModeFail"))
{
    ticket = queue.DefaultPrintTicket; // fall back to driver defaults
}

Prevention

When it happens

Trigger: Calling PrintQueue.GetPrintCapabilities/ptProvider.ConvertPrintTicketToDevMode with a PrintTicket whose XML is not well-formed, or when the native IPrintTicketProvider::ConvertPrintTicketToDevMode call returns a failure HRESULT for the target device.

Common situations: Hand-crafted or deserialized PrintTicket XML with invalid schema content; printer drivers that don't fully implement PrintTicket conversion; driver replaced/updated so cached ticket no longer matches; passing a ticket from one queue to another device.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTProvider.cs:505

                if (umDevMode != IntPtr.Zero)
                {
                    UnsafeNativeMethods.PTReleaseMemory(new HandleRef(this, umDevMode));
                    umDevMode = IntPtr.Zero;
                }
            }
            
            if ((hResult == (uint)NativeErrorCode.E_XML_INVALID) ||
                (hResult == (uint)NativeErrorCode.E_PRINTTICKET_FORMAT))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                              "{0} {1} {2}",
                              PrintSchemaTags.Framework.PrintTicketRoot,
                              PTUtility.GetTextFromResource("FormatException.XMLNotWellFormed"),
                              errorMsg),
                              nameof(printTicket));
            }

            throw new PrintQueueException((int)hResult,
                                              "PrintConfig.Provider.PT2DevModeFail",
                                              _deviceName,
                                              errorMsg);
        }

        public override void Release()
        {
            if (_providerHandle != null)
            {
                _providerHandle.Dispose();
                _providerHandle = null;
                _deviceName = null;
                _thread = null;
            }
        }

        #endregion Public Methods

View on GitHub (pinned to 81131a70a4)