1

I have a .net framework v4.7.2 WPF application that prints a FixedPage that has been running without any issues on Windows 7, but I've ran into some issues when running it on Windows 8.1.

The following code block is what causing the troubles:

private void Print()
{
    using (var printQueue = LocalPrintServer.GetDefaultPrintQueue())
    {
        var printTicket = printQueue.DefaultPrintTicket;
        var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
        writer.WritingCompleted += OnDocumentWritten;
        writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
    }
}

It throws a NullReferenceException with the following stack trace:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Collections.Hashtable.get_Item(Object key)
   at System.Printing.PrintQueue.get_IsXpsDevice()
   at System.Printing.PrintQueue.ForwardXpsDriverDocEvent(Object sender, XpsSerializationXpsDriverDocEventArgs args)
   at System.Windows.Xps.Serialization.XpsSerializationManager.OnXpsDriverDocEvent(XpsSerializationXpsDriverDocEventArgs e)
   at System.Windows.Xps.Serialization.XpsDriverDocEventManager.OnXpsDriverDocEvent()
   at System.Windows.Xps.Serialization.XpsDriverDocEventManager.ForwardPackagingProgressEvent(Object sender, PackagingProgressEventArgs e)
   at System.Windows.Xps.Packaging.PackagingProgressEventHandler.Invoke(Object sender, PackagingProgressEventArgs e)
   at System.Windows.Xps.Packaging.XpsInterleavingPolicy.AddItem(INode n, Int32 number, INode parent)
   at System.Windows.Xps.Serialization.XpsPackagingPolicy.AcquireXmlWriterForFixedPage()
   at System.Windows.Xps.Serialization.XpsSerializationManager.AcquireXmlWriter(Type writerType)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.get_XmlWriter()
   at System.Windows.Xps.Serialization.ReachTreeWalker..ctor(ReachSerializer serializer)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.PersistObjectData(SerializableObjectContext serializableObjectContext)
   at System.Windows.Xps.Serialization.ReachSerializerAsync.BeginSerializeObject(Object serializedObject)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.SerializeObject(Object serializedObject)
   at System.Windows.Xps.Serialization.XpsSerializationManagerAsync.InvokeSaveAsXamlWorkItem(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

If i replace writer.WriteAsync(...) with writer.Write(...) the error disappears.

I have been able to reproduce the error on Windows 8.1, Windows Server 2012 R2 and Windows Server 2016. I have not been able to reproduce the error on Windows 10.

Any suggestions on how to print asynchronously on Windows 8.1?

  • You probably need to keep the reference to that instance in printQueue alive, or at least don't call Dispose on it till printing has finished. It looks like you can defer Disposing to the OnDocumentWritten method. – rene Mar 22 '19 at 15:27
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Lews Therin Mar 22 '19 at 15:30
  • 1
    @rene the OP is using an async method inside the `using` block without awaiting it – Panagiotis Kanavos Mar 22 '19 at 15:34

2 Answers2

2

You could make the method async and then await the async call.

Try this:

private async Task Print()
{
    using (var printQueue = LocalPrintServer.GetDefaultPrintQueue())
    {
        var printTicket = printQueue.DefaultPrintTicket;
        var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
        writer.WritingCompleted += OnDocumentWritten;
        await writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
    }
}
laskdjf
  • 1,166
  • 1
  • 11
  • 28
0

@rene 's answer fixed the issue, so apparently the issue was that the PrintQueue was disposed before the printing finished.

private void Print()
{
    var printQueue = LocalPrintServer.GetDefaultPrintQueue()
    var printTicket = printQueue.DefaultPrintTicket;
    var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
    writer.WritingCompleted += OnDocumentWritten;
    writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
}

It does however seem odd, that the code worked on Windows 10 but not Windows 8.1.