Question

I am working on a WPF application that opens and displays XPS documents. When the application closes, the specification is the application should delete the opened XPS document for clean up. However, when opening a certain XPS document, the application throws an exception that the file is still in use when it tries to delete it. It is a little weird because it only happens when opening a particular XPS document and only when you have moved beyond the first page.

Some of the codes I used are shown below:

For opening the XPS Document:

DocumentViewer m_documentViewer = new DocumentViewer();
XpsDocument m_xpsDocument = new XpsDocument(xpsfilename, fileaccess);
m_documentViewer.Document = m_xpsDocument.GetFixedDocumentSequence();
m_xpsDocument.Close();

For navigating the XPS document:

m_documentViewer.FirstPage();
m_documentViewer.LastPage();
m_documentViewer.PreviousPage();
m_documentViewer.NextPage();

For closing the DocumentViewer object and deleting the file:

m_documentViewer.Document = null;
m_documentViewer = null;
File.Delete(xpsfilename);

It's all pretty basic and it works with the other documents that we tested. But with the particular XPS document, an exception pops up saying that the file to be deleted is still being used.

Is there something wrong or missing from my code?

Thanks!

Was it helpful?

Solution

Make the xpsDocument a member, then don't call close() on it :)

OTHER TIPS

You need to close the System.IO.Packaging.Package from which the XpsDocument assigned to the viewer was opened. Further, if you want to be able to open the same file again within the same application session, you will have to remove the Package from the PackageStore.

Try

var myXpsFile = @"c:\path\to\My XPS File.xps";
var myXpsDocument = new XpsDocument(myXpsFile);
MyDocumentViewer.Document = myXpsDocument;

//open MyDocumentViwer's Window and then close it
//NOTE: at this point your DocumentViewer still has a lock on your XPS file
//even if you Close() it
//but we need to do something else instead

//Get the Uri from which the system opened the XpsPackage and so your XpsDocument
var myXpsUri = myXpsDocument.Uri; //should point to the same file as myXpsFile

//Get the XpsPackage itself
var theXpsPackage = System.IO.Packaging.PackageStore.GetPackage(myXpsUri);

//THIS IS THE KEY!!!! close it and make it let go of it's file locks
theXpsPackage.Close();

File.Delete(myXpsFile); //this should work now

//if you don't remove the package from the PackageStore, you won't be able to
//re-open the same file again later (due to System.IO.Packaging's Package store/caching
//rather than because of any file locks)
System.IO.Packaging.PackageStore.RemovePackage(myXpsUri);

Yes, I know you probably didn't open the XpsDocument with a Package and might not even know what one is - or care - but .NET did it "for" you behind the scenes and forgets to clean up after itself.

http://blogs.msdn.com/junfeng/archive/2008/04/21/use-htrace-to-debug-handle-leak.aspx

You can figure out who holds the handle and the unmanaged stack using WinDbg

EDIT: And of course, you can also get the managed stack trace and poke around via the SOS extension (http://msdn.microsoft.com/en-us/library/bb190764.aspx)

Thanks for the reply!

It's a little low-level but I'll keep it in mind when I run out of ideas. Anyway, I found out a little more about the bug. The particular document that causes the exception have images inserted in them. When I remove the images, the exception doesn't happen. This could be a DocumentViewer bug maybe but I'm still trying...

Nope, so far still nothing.

Just to enumerate, I've tried the following methods that failed:

  1. Set everything to null in the "Closed" event of the window before deleting the file. This includes the DocumentViewer.Document property and the DocumentViewer object.

  2. Used ShowDialog() to open the window and set it to null afterwards. Moved the deletion of the file to the "Exit" event of the System.Windows.Application object that is opening the window. Still throws the exception that the file is being used.

DocumentViewer bug???

I suspect you are running into the same issue as http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic59281.aspx

Sounds like a bug in DocumentViewer it should have disposed of nested BitmapDecoders on close or loaded the image with a different bitmap caching option.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top