WPF DocumentViewer не выпускает файл XPS

Я работаю над приложением 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 появляется исключение, в котором говорится, что файл, который нужно удалить, все еще используется.

Есть ли что-то неправильно или отсутствует в моем коде?

Спасибо!

Ответ 1

Сделайте xpsDocument членом, затем не вызывайте его():)

Ответ 2

Вам нужно закрыть пакет System.IO.Packaging.Package, из которого был открыт XpsDocument, назначенный для просмотра. Кроме того, если вы хотите снова открыть тот же файл в одном сеансе приложения, вам придется удалить пакет из PackageStore.

Try

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

//open MyDocumentViwer 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 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 Package store/caching
//rather than because of any file locks)
System.IO.Packaging.PackageStore.RemovePackage(myXpsUri);

Да, я знаю, что вы, вероятно, не открыли XpsDocument с пакетом и, возможно, даже не знаете, что это такое - или заботитесь, но .NET сделал это для вас за кулисами и забыл очистить после себя.

Ответ 4

Спасибо за ответ!

Это немного низкоуровневый, но я буду иметь в виду, когда у меня заканчиваются идеи. Во всяком случае, я узнал немного больше об ошибке. В конкретном документе, который вызывает исключение, есть изображения, вставленные в них. Когда я удаляю изображения, исключение не происходит. Возможно, это может быть ошибка DocumentViewer, но я все еще пытаюсь...

Ответ 5

Нет, пока ничего.

Просто для перечисления, я пробовал выполнить следующие методы:

  • Перед удалением файла установите все значение null в событие "Закрыто" в окне. Это включает в себя свойство DocumentViewer.Document и объект DocumentViewer.

  • Используется ShowDialog(), чтобы открыть окно и установить его значение null после этого. Перемещено удаление файла в событие "Выход" объекта System.Windows.Application, который открывает окно. Все еще выдает исключение, которое используется в файле.

Ошибка DocumentViewer

Ответ 6

Я подозреваю, что вы столкнулись с той же проблемой, что и http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic59281.aspx

Звучит как ошибка в DocumentViewer, он должен был выложить вложенные BitmapDecoders на закрытие или загрузку изображения с помощью другого варианта кеширования растрового изображения.