dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.39k stars 4.75k forks source link

IOException when viewing XpsDocument with DocumentViewer #39430

Open MarioZ opened 4 years ago

MarioZ commented 4 years ago

I'm getting an IOException and "Entries cannot be opened multiple times in Update mode." message when providing XpsDocument to DocumentViewer control.

The issue occurs only in .NET Core, it doesn't occur in the .NET Framework.

I'm generating the XpsDocument in-memory and displaying it with DocumentViewer, but this issue can also be reproduced by creating the XpsDocument from the XPS file, see this repro project.

After loading the XPS file, you need to do some actions/movements on the DocumentViewer control and eventually, the exception will occur. For instance, you can zoom in and out, hover inside and outside, click inside and outside the control, etc. I didn't determine exactly what action causes the issue, sometimes it is on mouse movement, sometimes it is on mouse click...

Anyway, what I did notice is that the issue doesn't occur when file access is Read, not ReadWrite. Also, the issue doesn't occur when the XPS content doesn't contain any image.

System.IO.IOException
  HResult=0x80131620
  Message=Entries cannot be opened multiple times in Update mode.
  Source=System.IO.Compression
  StackTrace:
   at System.IO.Compression.ZipArchiveEntry.OpenInUpdateMode()
   at System.IO.Compression.ZipArchiveEntry.Open()
   at System.IO.Packaging.ZipStreamManager.Open(ZipArchiveEntry zipArchiveEntry, FileMode streamFileMode, FileAccess streamFileAccess)
   at System.IO.Packaging.ZipPackagePart.GetStreamCore(FileMode streamFileMode, FileAccess streamFileAccess)
   at System.IO.Packaging.PackagePart.GetStream(FileMode mode, FileAccess access)
   at MS.Internal.IO.Packaging.PackagePartExtensions.GetSeekableStream(PackagePart packPart, FileMode mode, FileAccess access)
   at System.IO.Packaging.PackWebResponse.CachedResponse.GetResponseStream()
   at System.IO.Packaging.PackWebResponse.GetResponseStream()
   at System.IO.Packaging.PackWebResponse.get_ContentType()
   at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
   at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
   at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
   at System.Windows.Media.Imaging.BitmapImage.EndInit()
   at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource, RequestCachePolicy uriCachePolicy)
   at System.Windows.Media.Imaging.BitmapImage..ctor(Uri uriSource)
   at System.Windows.Documents.FixedElement.GetImage()
   at System.Windows.Documents.FixedElement.GetObject()
   at System.Windows.Documents.FlowPosition.GetAdjacentElement(LogicalDirection dir)
   at System.Windows.Documents.FixedTextPointer.System.Windows.Documents.ITextPointer.GetAdjacentElement(LogicalDirection direction)
   at System.Windows.Documents.DocumentSequenceTextPointer.xGapAwareGetEmbeddedElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
   at System.Windows.Documents.DocumentSequenceTextPointer.GetAdjacentElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
   at System.Windows.Documents.DocumentSequenceTextPointer.System.Windows.Documents.ITextPointer.GetAdjacentElement(LogicalDirection direction)
   at System.Windows.Documents.TextEditorMouse.GetUIElementWhenMouseOver(TextEditor This, Point mouseMovePoint)
   at System.Windows.Documents.TextEditorMouse.UpdateCursor(TextEditor This, Point mouseMovePoint)
   at System.Windows.Documents.TextEditorMouse.OnMouseMoveWithoutFocus(TextEditor This, MouseEventArgs e)
   at System.Windows.Documents.TextEditorMouse.OnMouseMove(Object sender, MouseEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.MouseDevice.Synchronize()
   at System.Windows.Input.MouseDevice.OnHitTestInvalidatedAsync(Object sender, EventArgs e)
   at System.Windows.Input.InputManager.HitTestInvalidatedAsyncCallback(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)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   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)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at WpfApp1.App.Main()

  This exception was originally thrown at this call stack:
    [External Code]
Dotnet-GitSync-Bot commented 4 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

MarioZ commented 4 years ago

I don't have write-permissions, but I think the "area-System.IO.Compression" should be used, just like in #24962 and #27397.

Chapre commented 3 years ago

Any solution to this? having the really same issue

MarioZ commented 3 years ago

@Chapre how exactly are you creating your XpsDocument?

In my case, I was able to obtain an XPS stream which enabled me to do this file access change in memory:

MemoryStream xpsStream = ...

var package = Package.Open(xpsStream, FileMode.Open, FileAccess.Read);
var uri = new Uri($"memorystream://{Guid.NewGuid():N}.xps");
PackageStore.AddPackage(uri, package);

this.xps = new XpsDocument(package, CompressionOption.NotCompressed, uri.AbsoluteUri);
this.viewer.Document = this.xps.GetFixedDocumentSequence();
MykolaKhilko commented 3 years ago

@MarioZ i got the same exception, but when i tried to write the xps document with pagination. And i saw your question on closed issue that looks more like mine. My solution was divide read and write file access

` .... //saving flow document as xps using (var xpsDocument = new XpsDocument(TempFileName, FileAccess.Read)) //was FileAccess.ReadWrite { FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence(); var documentPaginator documentPaginator = fixedDocSeq.DocumentPaginator; ... using (var newDoc = new XpsDocument(fileName, FileAccess.Write)) { ... XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(PrintQueue); .... writer.Write(documentPaginator); xpsDocument.Close();
} }

...

` Something like this in .net 5.0

Sorry for formatting, my first comment ever

PeterPandefu commented 2 years ago

I have the same problem,please fix it soon

PeterPandefu commented 2 years ago

What's more, I can't print,Using XpsDocument with DocumentViewer

danmoseley commented 2 years ago

Would you be interested in debugging into it @PeterPandefu ?

PeterPandefu commented 2 years ago

Would you be interested in debugging into it @PeterPandefu ?

what should I do?

PeterPandefu commented 2 years ago

Would you be interested in debugging into it @PeterPandefu ?

Is such that. I have the same problem as him@MarioZ. I using XpsDocument with DocumentViewer and FlowDocument in WPF, LoadXps like this: using (MemoryStream ms = new MemoryStream()) { using (Package package = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite)) { Uri DocumentUri = new Uri("pack://InMemoryDocument.xps"); PackageStore.RemovePackage(DocumentUri); PackageStore.AddPackage(DocumentUri, package); using (XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.Fast, DocumentUri.AbsoluteUri)) { XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument); //m_doc is FlowDocument; writer.Write(((IDocumentPaginatorSource)m_doc).DocumentPaginator); docViewer.Document = xpsDocument.GetFixedDocumentSequence(); xpsDocument.Close(); } } } } catch (Exception ex) { throw; }

If My FlowDocument Contain Image ,This error will appear,otherwise no And The issue occurs only in .NET Core, it doesn't occur in the .NET Framework. I don't konw my description is detailed? I wish you can help me.Thanks!