WPF DocumentViewer无法释放XPS文件

10

我正在开发一款WPF应用程序,可以打开并显示XPS文档。当应用程序关闭时,规范要求应该删除已经打开的XPS文档以进行清理。但是,当打开某个特定的XPS文档时,应用程序会抛出异常,指出在尝试删除文件时文件仍在使用中。这有点奇怪,因为它只会在打开特定的XPS文档并且在第一页之后移动到其他页面时才会出现。

下面是我使用的一些代码:

打开XPS文档的代码:

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

导航XPS文档:

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

关闭DocumentViewer对象并删除文件的方法:

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

这一切都非常基础,而且它与我们测试过的其他文档一起运行。但是对于特定的XPS文档,会弹出一个异常,称要删除的文件仍在使用中。

我的代码有什么问题或遗漏吗?

谢谢!

6个回答

7
你需要关闭打开XpsDocument的System.IO.Packaging.Package。此外,如果你想在同一应用程序会话中再次打开相同的文件,则必须从PackageStore中删除该Package。
尝试:
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);

是的,我知道你可能没有用Package打开XpsDocument,甚至可能不知道什么是Package,也不在意,但.NET已经在幕后为你完成了这项工作,并忘记清理它自己。


2
将xpsDocument作为成员变量,然后不要在其上调用close()方法 :)

嘿,这个方法可行!我只是让XpsDocument对象保持打开状态,在退出时调用XpsDocument.Close(),然后就可以删除文件了。感谢moogs! - bjutus
1
这仅在您可以关闭应用程序以释放锁定时起作用。如果您需要在应用程序保持打开状态时释放锁定,则需要参见下面的答案或https://dev59.com/90nSa4cB1Zd3GeqPNmiq。 - Tim Erickson

0

0

0

感谢回复!

虽然有点低级,但当我没有想法时,我会记在心里的。 无论如何,我发现了更多关于这个错误的信息。导致异常的特定文档中插入了图像。当我删除图像时,异常就不会发生。这可能是DocumentViewer的一个bug,但我仍在努力解决...


0

没有,到目前为止还是没有什么进展。

列举一下,我尝试了以下失败的方法:

  1. 在窗口的“Closed”事件中将所有内容设置为null,然后再删除文件。这包括DocumentViewer.Document属性和DocumentViewer对象。

  2. 使用ShowDialog()打开窗口,然后将其设置为null。将文件的删除移动到正在打开窗口的System.Windows.Application对象的“Exit”事件中。仍然会抛出文件正在使用的异常。

DocumentViewer有bug吗???


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接