Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET core WPF print dialog freeze/not supported exception #2609

Open
Zubastic opened this issue Feb 19, 2020 · 13 comments
Open

.NET core WPF print dialog freeze/not supported exception #2609

Zubastic opened this issue Feb 19, 2020 · 13 comments
Assignees
Labels
Bug Product bug (most likely) urgent status: This issue needs immediate attention

Comments

@Zubastic
Copy link

Zubastic commented Feb 19, 2020

  • .NET Core Version: 3.1.101, 3.1.102
  • Windows version: 1607 14393.3504
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: No
  • Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No

Problem description:
After select print button error appears.

Actual behavior:
NotSupportedException when I selected virtual printer (for example Microsoft Print to PDF). When selected in dialog real one - nothing happends, just app became unresponsible for infinity time. At debugger it stuck at WaitHandle:

изображение

System.NotSupportedException: Specified method is not supported.
   at MS.Internal.PrintWin32Thunk.XpsPrintJobStream.Seek(Int64 offset, SeekOrigin origin)
   at System.Printing.PrintQueueStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.Compression.ZipArchive.WriteFile()
   at System.IO.Compression.ZipArchive.Dispose(Boolean disposing)
   at System.IO.Compression.ZipArchive.Dispose()
   at System.IO.Packaging.ZipPackage.Dispose(Boolean disposing)
   at System.IO.Packaging.Package.System.IDisposable.Dispose()
   at System.IO.Packaging.Package.Close()
   at System.Windows.Xps.Packaging.XpsDocument.DisposeXpsDocument()
   at System.Printing.PrintQueue.DisposeSerializationManager(Boolean abort)
   at System.Windows.Xps.XpsDocumentWriter.EndWrite(Boolean disposeManager, Boolean abort)
   at System.Windows.Xps.XpsDocumentWriter.SaveAsXaml(Object serializedObject, Boolean isSync)
   at System.Windows.Xps.XpsDocumentWriter.Write(DocumentPaginator documentPaginator, PrintTicket printTicket)
   at System.Windows.Controls.PrintDialog.PrintDocument(DocumentPaginator documentPaginator, String description)
   at WpfNetcoreTest.Program..ctor() in C:\Users\Zubastic\Source\Repos\Zubastic\PrintDialogBug\WpfNetcoreTest\Program.cs:line 18
   at WpfNetcoreTest.App..ctor() in C:\Users\Zubastic\Source\Repos\Zubastic\PrintDialogBug\WpfNetcoreTest\App.xaml.cs:line 18
   at WpfNetcoreTest.App.Main()

Expected behavior:
I could print PDF document at printer/save pdf file.

Minimal repro:
Repo for reproduce bug:
https://github.com/Zubastic/PrintDialogBug

@rladuca could u help me with that issue? 1607 is important for me, because enterprise use LTSB version. At 1809 and newer version all is good.

@dmarcello53
Copy link

Oh well !

@hnhai
Copy link

hnhai commented Aug 14, 2020

Any dotnet core version fixed this bug ? @dmarcello53 . Please

@Zubastic
Copy link
Author

@hnhai windows 1903 and newer is fixed.

@Zubastic
Copy link
Author

bump, @danmosemsft could you help with this issue?

@danmoseley
Copy link
Member

@Zubastic unfortunately i don't have knowledge of WPF code. Does this mean printing is just broken or only in this particular repo?

@ryalanms is the primary developer in this repo - perhaps he can help.

@Zubastic
Copy link
Author

Zubastic commented Aug 19, 2020

@danmosemsft it depends on windows version. At 1607 its broken (LTSB for enterprise users), at 1809 or newer - it is OK. But enterprise couldn't update :(
Thank you for assistance.

@danmoseley
Copy link
Member

cc @fabiant3 also

@Zubastic
Copy link
Author

Zubastic commented Aug 20, 2020

Well, additional info about bug:

class System.Printing.PrintQueue
1809:
1809

1607:
1607

if (this.IsXpsOMPrintingSupported()) returning true for 1809 and false for 1607. After that flag this.isWriterAttached is set. And at dispose method exception was thrown at ZipPackage.Dispose() (all stack at first post).
Check ?isXpsOMPrintingSupported@?1??IsXpsOMPrintingSupported@PrintQueue@Printing@System@@QE$AAM_NXZ@$$Q4_NA; returning different values.

@rladuca
Copy link
Member

rladuca commented Aug 20, 2020

IsXpsOMPrintingSupported is pegged to Windows 10 1703 (RS2) and above. This has always been this way since its inception (in .NET Framework, I believe in the 4.7/4.7.1 timeframe).

The problem is likely to be that the serialization manager for the legacy path, NgcSerializationManager, is likely not managing streams in a way conducive to the new underlying packaging libraries. This is, generally, the root cause of almost all printing (and XPS for that matter) issues in .NET Core. The management of streams for packages needs to be overhauled to match System.IO.Packaging and System.IO.Compression. The old assumptions WPF is built on when it contained its own packaging and zip libraries no longer apply.

This isn't a workaround, but a potential test. If you force the value there to be true (perhaps forcing the static underlying the function call here) do things work? Note there may be other instances where another piece of code needs to pivot on this sort of check for printing support, but I don't have a full understanding of all of those places (@miguep maybe?).

@ryalanms One thing you might want to check is if you can just remove the OS check or extend support for it downward. The minimum client is low, but this was guarded so as to not explicitly change behavior on applications targeting lower versions. For .NET Core it might make sense to remove this and move forward. It would need good testing, but might help alleviate the pain of fixing up the legacy serialization classes. Of course, that could just be the outside layer of issues, I haven't tried.

@Zubastic
Copy link
Author

This isn't a workaround, but a potential test. If you force the value there to be true (perhaps forcing the static underlying the function call here) do things work?

I change check if (this.IsXpsOMPrintingSupported()) to true and get this exception:
Exception

@Zubastic
Copy link
Author

Well, if change flag to false and return NgcSerializationManager, it work.
flag

@ryalanms ryalanms self-assigned this Aug 24, 2020
@ryalanms ryalanms added this to the 5.0.0 milestone Aug 24, 2020
@ryalanms ryalanms added the urgent status: This issue needs immediate attention label Aug 24, 2020
@ericstj
Copy link
Member

ericstj commented Oct 26, 2020

cc @stevenbrix @rladuca

This appears related to a57ed01

In this case, based on the callstack, it seems that PrintQueueStream is exposing CanSeek (and CanRead) as true

Boolean
PrintQueueStream::CanRead::
get(
void
)
{
return true;
}
Boolean
PrintQueueStream::CanWrite::
get(
void
)
{
return true;
}
Boolean
PrintQueueStream::CanSeek::
get(
void
)
{
return true;
}

But then is directly calling down to the SpoolStream:

return printerThunkHandler->SpoolStream->Seek(offset, origin);

And the SpoolStream is created with CanRead as false

spoolerStream = gcnew XpsPrintJobStream((IXpsPrintJobStream *)tempDocStream, tempCompletedEvent, false, true);

and hardcodes CanSeek to false:
Boolean
XpsPrintJobStream::CanSeek::
get(
void
)
{
return false;
}

Perhaps the fix here is to simply update PrintStream to delegate the Can* properties to the SpoolStream like it is doing for the actual Read|Write|Seek methods. That will let the calling code "know" that the backing stream cannot read or seek and write the Package/ZipArchive in a way that doesn't do any seeking.

@ryalanms
Copy link
Member

ryalanms commented Jul 28, 2021

This was fixed in .NET 5.0 in our internal repo (in PresentationNative), but was not backported to 3.1.

/cc @dotnet/wpf-developers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Product bug (most likely) urgent status: This issue needs immediate attention
Projects
None yet
Development

No branches or pull requests

10 participants