Open bgrainger opened 2 months ago
This is a regression from .NET Framework 4.7.2
I had to update the sample app slightly to work correctly under .NET 4.7.2 (but the primary point still stands). The updated code runs under net472 but still crashes under net8.0-windows.
Replace the two lines to create the XpsDocument
with:
// create a temporary package
var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Package package = Package.Open(tempFilePath, FileMode.Create, FileAccess.ReadWrite);
// create a temporary XPS document using that package
string tempFilePath2 = Path.GetTempFileName();
PackageStore.AddPackage(new Uri(tempFilePath2), package);
var tempDocument = new XpsDocument(package, CompressionOption.Normal, tempFilePath2);
See https://github.com/bgrainger/Bug6842/commit/409cf4caefd1b323ebc0d6b7db3c2233285994aa.
Suggestion:
If you could write directly to FlowDocument, there is no need to nest another layer of XpsDocument. In this case, just use printWriter.Write(((IDocumentPaginatorSource) flowDocument).DocumentPaginator, printTicket);
Analysis: According to the error message, the XpsDocument is opened multiple times. writer.Write(((IDocumentPaginatorSource)flowDocument).DocumentPaginator); and printWriter.Write(tempDocument.GetFixedDocumentSequence(), printTicket); both need to open the XpsDocument for reading and writing.
I tried using Close() to close the first opening, but it didn't seem to work.
In the official sample program (https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/documents/printing-overview?view=netdesktop-8.0#xpsdocumentwriter), it also seems to avoid opening the XpsDocument file multiple times for reading and writing.
The FlowDocument is a simplification for this repro; it's not used by the application where this problem was first discovered (which uses a custom DocumentPaginator and draws directly to a Visual, then saves everything to an XpsDocument so it can show a "print preview" on screen, then prints that XpsDocument).
The exception is coming from OpenInUpdateMode
. This seemed odd to me, because we should just be "reading" the document to print it, not updating it.
ZipPackage
sets the ZipArchiveMode
to Update
if it's opened with FileAccess.ReadWrite
: https://github.com/dotnet/runtime/blob/31bc167803abe8381c6ecdfec1f7935dead2df10/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs#L395-L396
That value comes from Package.Open
: https://github.com/dotnet/runtime/blob/31bc167803abe8381c6ecdfec1f7935dead2df10/src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs#L854
That value comes from the XpsManager
constructor: https://github.com/dotnet/wpf/blob/0be453cffbc6cd30dfc96a0f48c48f7bb0754171/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsManager.cs#L140-L159
Which comes from the XpsDocument
constructor: https://github.com/dotnet/wpf/blob/0be453cffbc6cd30dfc96a0f48c48f7bb0754171/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs#L156-L166
Thus, it seems like the bug may be getting triggered from printing an XPS Document that is still open for writing. I updated the code to close and reopen the document. This allows it to be printed successfully: https://github.com/bgrainger/Bug6842/commit/4d5eabc5419fbfa12218c0beed2464eed7585ab6.
I have applied this fix to our complex WPF application and it resolves the bug.
I believe this is still a regression from .NET Framework (and perhaps could manifest in other code paths?) but it is now less serious for us.
Description
This is a repost of https://github.com/dotnet/wpf/issues/6842 with a repro.
In a WPF application ported to .NET 8.0 from .NET Framework 4.7.2, printing a complex document throws an exception, and nothing prints. (The Microsoft Print to PDF driver writes a 0-byte file.)
Reproduction Steps
Clone https://github.com/bgrainger/Bug6842. Build and run the app. Press the Print button. (If your default printer is "Print to PDF" or similar, specify a file name to print to when the Save dialog appears.) The application crashes.
The minimal code to repro is:
Expected behavior
The FlowDocument (with an embedded image) is printed to the selected printer.
Actual behavior
The application crashes and nothing is printed.
Regression?
This is a regression from .NET Framework 4.7.2 and affects my company's product that was ported from that version.
It was present in .NET 6.0 (see https://github.com/dotnet/wpf/issues/6842).
Known Workarounds
Yes; see comment: https://github.com/dotnet/wpf/issues/9418#issuecomment-2239850721.
Impact
Our application can't print on Windows when running on .NET 8.0.
Configuration
Other information
A possible fix is in this PR: https://github.com/dotnet/wpf/pull/6843.