如何获得WPF的DocumentViewer在源XPS Document上释放其文件锁? [英] How do I get WPF's DocumentViewer to release its file lock on the source XPS Document?

查看:410
本文介绍了如何获得WPF的DocumentViewer在源XPS Document上释放其文件锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在WPF DocumentViewer中显示XPS文件并关闭DocumentViewer实例后,XPS文件被锁定,我无法删除它.我需要释放XPS文件上的锁,以便可以删除它,写另一个具有相同名称的文件,并可以选择在新的DocumentViewer实例中显示该新XPS文件.我需要在同一个应用程序实例中执行此操作-无需关闭应用程序(这是打印预览"方案).

After showing an XPS file in the WPF DocumentViewer, and closing the DocumentViewer instance, the XPS file is locked and I cannot delete it. I need to release the lock on the XPS file so I can delete it, write another one with the same name, and optionally display that new XPS file in a new DocumentViewer instance. I need to do this in the same app instance - without having to close the app (this is a Print Preview scenario).

换句话说,如何在不向"File.Delete(tempXpsFile);"抛出异常的情况下运行以下代码?声明?

In other words, how would I get the following code to run without throwing an exception at the "File.Delete(tempXpsFile);" statement?

var tempXpsFile = @"c:\path\to\Temporary.xps";

var previewWindow = new Window();
var docViewer = new DocumentViewer();
previewWindow.Content = docViewer;

GenerateXpsFile(tempXpsFile);

var xpsDocument = new XpsDocument(tempXpsFile);

previewWindow.ShowDialog();

File.Delete(tempXpsFile);  //this will throw an exception due to a file lock on tempXpsFile

GenerateXpsFile(tempXpsFile); //assume this generates a different file
//otherwise the scenario doesn't make sense as we could just skip the above delete
//and this statement and re-use the same file

previewWindow = new Window();
docViewer = new DocumentViewer();
previewWindow.Content = docViewer;

previewWindow.ShowDialog();

关闭应用程序确实会释放文件锁定,如 WPF DocumentViewer不会提到的那样不会释放XPS文件,但是在这种情况下这不是一个选择.

Closing the app does release the file lock, as mentioned in WPF DocumentViewer doesn't release the XPS file, but that is not an option in this scenario.

推荐答案

您需要关闭从中打开分配给查看器的XpsDocument的System.IO.Packaging.Package.此外,如果您希望能够在同一应用程序会话中再次打开同一文件,则必须从PackageStore中删除该Package.关闭软件包将释放文件锁,并允许您删除文件,但是之后您将无法重新打开该文件(或更确切地说,即使该文件具有相同的名称,也无法以相同的名称重新打开该文件)不同的内容),直到从PackageStore中删除Package.

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. Closing the Package will release the file lock and allow you to delete the file, but you will not then be able to re-open that same file (or, more precisely, any file at that same location by the same name even if it has different content) until you remove the Package from the PackageStore.

在问题代码的上下文中,在第一个PreviewWindow.ShowDialog()之后插入以下内容:在File.Delete(tempXpsFile);之前

In the context of the code in the question, insert the following after the first previewWindow.ShowDialog(); before the File.Delete(tempXpsFile);

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

//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();

//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);

因此问题中出现的固定代码段变为:

So the fixed code segment presented in the question becomes:

var tempXpsFile = @"c:\path\to\Temporary.xps";

var previewWindow = new Window();
var docViewer = new DocumentViewer();
previewWindow.Content = docViewer;

GenerateXpsFile(tempXpsFile);

var xpsDocument = new XpsDocument(tempXpsFile);

previewWindow.ShowDialog();

//BEGIN NEW CODE
var myXpsUri = xpsDocument.Uri; //should point to the same file as tempXpsFile
var theXpsPackage = System.IO.Packaging.PackageStore.GetPackage(myXpsUri);
theXpsPackage.Close();
System.IO.Packaging.PackageStore.RemovePackage(myXpsUri);
//END NEW CODE

File.Delete(tempXpsFile);  //this will succeed now

GenerateXpsFile(tempXpsFile);

previewWindow = new Window();
docViewer = new DocumentViewer();
previewWindow.Content = docViewer;

previewWindow.ShowDialog();

是的,我知道我没有使用程序包打开XpsDocument-.NET在幕后为我为"我,却忘了自己清理.

Yes, I know I didn't open the XpsDocument with a Package - .NET did it "for" me behind the scenes and forgets to clean up after itself.

这篇关于如何获得WPF的DocumentViewer在源XPS Document上释放其文件锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆