Frage

eine XPS-Datei im WPF Document Nachdem wir gezeigt haben, und Schließen des Document Fall wird die XPS-Datei gesperrt und ich kann es nicht gelöscht werden. Ich brauche die Sperre für die XPS-Datei freizugeben, damit ich es löschen kann, ein anderes mit dem gleichen Namen zu schreiben, und gegebenenfalls in einem neuen Document Beispiel, dass neue XPS-Datei angezeigt werden soll. Ich brauche dies in der gleichen App-Instanz zu tun -., Ohne die App (dies ist ein Druckvorschau-Szenario)

schließen

Mit anderen Worten, wie würde ich den folgenden Code erhalten, ohne Auslösen einer Ausnahme am laufen „File.Delete (tempXpsFile);“ Aussage?

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

die App Schließen funktioniert die Dateisperre freigeben, wie erwähnt in WPF Document doesn ‚t die XPS-Datei freigeben, aber das ist keine Option in diesem Szenario.

War es hilfreich?

Lösung

Sie müssen die System.IO.Packaging.Package, aus dem das XpsDocument zugewiesen den Betrachter schließen eröffnet. Wenn Sie darüber hinaus die gleiche Datei wieder in der gleichen Anwendungssitzung zu öffnen, in der Lage sein wollen, müssen Sie das Paket aus dem Packages zu entfernen. Schließen der Packung wird die Dateisperre freigeben und ermöglichen es Ihnen, die Datei zu löschen, aber Sie werden wieder zu öffnen, dass gleiche Datei (oder, genauer gesagt nicht dann in der Lage sein, eine beliebige Datei an derselben Stelle mit dem gleichen Namen, auch wenn es hat unterschiedliche Inhalte), bis Sie das Paket aus dem Packages entfernen.

Im Rahmen des Codes in der Frage, legen Sie die folgenden nach dem ersten previewWindow.ShowDialog (); bevor die 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 ist das feste Codesegment in der Frage vorgelegt wird:

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

Ja, ich weiß, dass ich nicht die XpsDocument mit einem Paket geöffnet hat - .NET tat es „für“ mich hinter den Kulissen und vergisst nach sich aufzuräumen

.

Andere Tipps

Nicht sicher, welche Version von .Net diese Frage ursprünglich in Bezug auf, oder ob diese zwischen 3.x und 4.x, verändert vielleicht habe aber von einigen Untersuchungen gegen .Net 4.0 sieht gefragt wurde, wie die Lösung sein könnte ziemlich viel einfacher als das.

XpsDocument IDisposable implementieren, was darauf hindeutet muss es entsorgen () 'd nach dem Gebrauch sein. Die Falte ist, dass IDisposable.Dispose () so ausgebildet, dass sie versteckt ist, so dass Sie es nicht direkt aufrufen können. Sie müssen stattdessen Close () nennen. Mit dotPeek analysieren XpsDocument.Dispose ():

  • XpsDocument.Close () ruft XpsDocument.Dispose ()
  • XpsDocument.Dispose () ruft XpsManager.Close ()
  • XpsManager.Close () ruft XpsManager.RemovePackageReference ()
  • XpsManager.RemovePackageReference () ruft PackageStore.RemovePackage () und Package.Close ()

Also, wenn ich etwas fehlt, nur Close () ing die XpsDocument (die man eigentlich sind sowieso zu tun) sollte das gleiche Ergebnis erzielen, ohne in das interne Paket-Management-Zeug zu graben, die XpsDocument Handhabung werden sollte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top