1

I'm using the XpsDocumentWriter class (MSDN) - specifically using the WriteAsync(FixedDocument) method.

Here is the code I am using to call this WriteAsync method:

PrintDocumentImageableArea area = null;
var xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(ref area);

var fixedDocument = GenerateDocument();

xpsDocumentWriter.WritingCompleted += DocumentWriterOnWritingCompleted;

try
{
    xpsDocumentWriter.WriteAsync(fixedDocument);
}
catch
{
    Console.WriteLine("Error occurred");
}

The issue that I have is that when I print a document to say test.pdf, if I open that file in a PDF viewer, and then try to print to that filename again, it throws an exception (due to the file being open) - this exception is caught in the try-catch statement above.

This is fine on my PC, and on a few other peoples PCs, but there's 2 PCs I've located that when subject to the same circumstances, they don't throw an exception. I've also checked the WritingCompleted event for errors, using the following code:

private void DocumentWriterOnWritingCompleted(object sender, WritingCompletedEventArgs e)
{
    if (e.Error != null)
    {
        Console.WriteLine("Error has occurred");
    }
}

This code does not catch anything on those machines in question.

Additional information - I've checked, and the document is NOT overwritten on the PCs where no error is detected, it simply fails to write the document silently. The WritingCompleted event is fired on all machines, but no errors on any.

The weirdest part is that this is the code I temporarily set up to create the FixedDocument:

public FixedDocument DocumentGenerator()
{
    FixedDocument fixedDocument = new FixedDocument();

    for (int numberOfPages = 0; numberOfPages < 50; numberOfPages++)
    {
        PageContent pageContent = new PageContent();

        FixedPage fixedPage = new FixedPage()
        {
            Width = new Size(96 * 8.5, 96 * 11).Width,
            Height = new Size(96 * 8.5, 96 * 11).Height
        };

        //Add a canvas with a TextBlock and a Rectangle as children.
        Canvas canvas = new Canvas();
        fixedPage.Children.Add(canvas);
        TextBlock textBlock = new TextBlock();
        textBlock.Text =
            string.Format("Page {0} / {1}\n\nThis Is Page {0}.",
                i + 1, 1000);
        textBlock.FontSize = 24;
        canvas.Children.Add(textBlock);
        Rectangle rect = new Rectangle();
        rect.Width = 200;
        rect.Height = 200;
        rect.Fill =
            new SolidColorBrush(Color.FromArgb(200, 20, 50, 200));
        canvas.Children.Add(rect);
        ((IAddChild)pageContent).AddChild(fixedPage);

        fixedDocument.Pages.Add(pageContent);
    }

    return fixedDocument;
}

When numberOfPages is ~> 30, no error is shown on the problem PC, but when the numberOfPages is ~< 20, an error IS shown on the problem PC. These boundaries change depending on what is being rendered on the page (so it appears to be dependent on size/complexity of document somehow).

So I was wondering if anyone's ever seen anything like this before? Why on earth would the content that is in the FixedDocument have any effect on whether an error is thrown due to attempting to overwrite a file that is locked by another program?

AidanH
  • 502
  • 5
  • 24
  • Further details available here: https://developercommunity.visualstudio.com/content/problem/732522/xpsdocumentwriter-silent-failure.html – AidanH Sep 12 '19 at 09:59

1 Answers1

0

Trying to handle a file being open in a catch is probably not the best design (though I admit I have programs out there that have done that). You are better off determining if the file is open first, then if it is not, allow it to be overwritten.

This way you aren't relying on error handling to determine it for you. I have seen instances where a pdf will open in Edge instead of Adobe and totally bypass any file in use exceptions (not good).

Example

if(IsFileOpen(myfile))
{
     xpsDocumentWriter.WriteAsync(fixedDocument);
}
else
{
     //Display error message
}

Reference this post for determining how to check if a file is open.

Tronald
  • 1,520
  • 1
  • 13
  • 31
  • Oh nice, I've never thought about doing it like that - only issue is that the 'WriteAsync' method opens the file save dialog and the print selection menu, therefore putting a 'IsFileOpen' before the 'WriteAsync' means that there's opportunity while either the print selection dialog or file save dialog is open for the user to open a PDF (and then overwrite it in the file save menu) - meaning that this would not be a concrete fix. – AidanH Sep 12 '19 at 07:01