Error when printing to Microsoft Print to PDF printer at the same time from multiple threads/apps

2

We have a console application that uses PrintDocument in C# to create a PDF using the built in "Microsoft Print to PDF" printer in Windows 10/Server 2016. We use Microsoft's HPC Pack, so this application may run multiple times on the same server -- with both applications trying to print to the same printer at the same time. Every now and then, one of the files will end up being 0 bytes in size. I can also find a few errors in the event log.

I have tried deleting all other printers except for Microsoft Print to PDF. I tried setting different advanced options in the printer settings (like spooling -- so that it will wait until the last page until is spooled).

In our code, I am currently checking for the file size after I think it should be generated -- and if it is 0 bytes, I retry for up to 3 times. This is working, but I was wondering if there was a better fix for it.

I also tried to change the isolation level of the printer's driver -- but that option was disabled for that printer.

The following code should replicate the issue. Before running, you should open Event Viewer, and go to Applications and Services Logs --> Microsoft --> Windows --> PrintService. Right click on the "Operational" log and choose to "enable" it. Both the "Admin" log and "Operational" log will have entries if a failure occurs.

    static class Program
    {
        static void Main()
        {
            var tester = new PrintPdfTest();
            tester.CleanupPrev(@"C:\temp\");
            tester.Run(@"C:\temp\", 5);
        }
    }

    public class PrintPdfTest
    {
        private EventWaitHandle m_waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);

        public void CleanupPrev(string dir)
        {
            foreach (var file in Directory.GetFiles(dir, "file*.pdf"))
                File.Delete(file);
        }

        public void Run(string dir, int nbrOfFiles)
        {
            var threads = new List<Thread>();

            m_waitHandle.Reset();
            for (int i = 0; i < nbrOfFiles; i++)
            {
                var fileName = Path.Combine(dir, $"file{i}.pdf");
                var t = new Thread(ThreadMethod);

                threads.Add(t);
                t.Start(fileName);
            }

            // All threads created -- let them go
            Thread.Sleep(1000);
            m_waitHandle.Set();

            foreach (var thread in threads)
                thread.Join();

            threads.Clear();
            m_waitHandle.Dispose();
            m_waitHandle = null;

            Thread.Sleep(1000);
            for (int i = 0; i < nbrOfFiles; i++)
            {
                var fileName = Path.Combine(dir, $"file{i}.pdf");
                if (File.Exists(fileName))
                {
                    var info = new FileInfo(fileName);
                    System.Diagnostics.Debug.WriteLine($"File {fileName} has size: {info.Length}");
                }
            }

        }

        private void ThreadMethod(object state)
        {
            using (var printDoc = new PrintDocument())
            {
                printDoc.PrintPage += PrintDoc_PrintPage;
                printDoc.DefaultPageSettings.Landscape = true;

                var settings = printDoc.PrinterSettings;
                settings.PrinterName = "Microsoft Print to PDF";
                settings.PrintToFile = true;
                settings.PrintFileName = (string)state;

                m_waitHandle.WaitOne();
                printDoc.Print();
            }
        }

        private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.DrawString(
                "This is a test",
                new System.Drawing.Font("Arial", 8),
                System.Drawing.Brushes.Black,
                30f, 30f);
        }
    }

After running the code, look in your C:\Temp folder for files named "file*.pdf" -- if any of them are 0 bytes in size, then the issue has occurred.

When the issue occurs, these are these types of events in the log file:

Event ID: 824 Task Category: Executing print filters in the spooler pipeline Level: Error A fatal error occurred while printing job document, id 6 on the print queue Microsoft Print to PDF. The print filter pipeline process was terminated. Error information: 0x88985006.

Event ID: 842 Task Category: Isolating printer drivers and other plug-ins Level: Information The print job 6 was sent through the print processor MS_XPS_PROC on printer Microsoft Print to PDF, driver Microsoft Print To PDF, in the isolation mode 0 (0 - loaded in the spooler, 1 - loaded in shared sandbox, 2 - loaded in isolated sandbox). Win32 error code returned by the print processor: 0x88985006.

The document Print Document, owned by {username}, failed to print on printer Microsoft Print to PDF. Try to print the document again, or restart the print spooler. Data type: RAW. Size of the spool file in bytes: 80201. Number of bytes printed: 80201. Total number of pages in the document: 1. Number of pages printed: 0. Client computer: \computername. Win32 error code returned by the print processor: 2291683334. The given interface is already registered.

c#
hpc
asked on Stack Overflow Oct 2, 2019 by crwells

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0