ObjectDisposed第二次XPS导出的异常

时间:2017-03-22 19:52:46

标签: c# wpf mvvm

我有一个用于在文档查看器中打开文件的应用程序,用于1:不允许用户更改文件,2:跟踪打开的文件以及打开的时间。< / p>

也就是说,我将他们选择的文件(Word Docs或Excel工作簿)转换为XPS文件并放在WPF项目的DocumentViewer中。

第一次打开文档时,它按预期工作。但是,只要尝试打开第二个文件,我就会得到一个

  

System.ObjectDisposedException:包对象已关闭并处置,因此无法对此对象或此包的一部分上打开的任何流执行操作。

我现在一直在寻找几个小时,不知道发生了什么。

以下是相关代码:

class DocumentViewerFileGenerator
     {


        /// <summary>
        /// Generates a docuemnt, of the IDocumentPaginatorSource type to be used by the document viewer in the
        /// view. By looking at the extension type, decides on which interop to use.
        /// </summary>
        /// <param name="filePath">Path of the file that is to be converted</param>
        /// <param name="extension">Extension of the file. Makes it easier for the if's</param>
        /// <returns>A converted IDocumentPaginatorSource version of the file to be viewed.</returns>
        public XpsDocument GenerateDocumentForViewer(string filePath, string extension)
        {

            string tempOutputPath = Environment.CurrentDirectory + @"\temp.xps";
            ClearOldTemp(tempOutputPath);

            XpsDocument xpsDocument;
            if (extension == ".doc" || extension == ".docx")
            {
               ConvertWordToXps(filePath, tempOutputPath);
            }

            if (extension == ".xls" || extension == ".xlsx")
            {
               ConvertExcelToXps(filePath, tempOutputPath);
            }

            xpsDocument = MakeFixedDocument(tempOutputPath);

            return xpsDocument;
        }

        /// <summary>
        /// Just clears out the old temp path
        /// </summary>
        /// <param name="tempOutputPath"></param>
        private void ClearOldTemp(string tempOutputPath)
        {
            if (File.Exists(tempOutputPath))
            {
                File.Delete(tempOutputPath);
            }
        }

        /// <summary>
        /// Converts the file selected, through Word, into an XPS for conversion purposes.
        /// </summary>
        /// <param name="filePath">The file to be converted. Full path needed.</param>
        private void ConvertWordToXps(string filePath, string tempOutputPath)
        {
            Word.Application word = new Word.Application();
            word.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
            word.Visible = false;
            Word.Document document = word.Documents.Open(filePath);
            document.SaveAs2(tempOutputPath, FileFormat: Word.WdSaveFormat.wdFormatXPS);
            document.Close();
            word.Quit();
            Marshal.ReleaseComObject(document);
            Marshal.ReleaseComObject(word);
        }

        /// <summary>
        /// Converts the file selected, through Excel, into an XPS for conversion purposes.
        /// </summary>
        /// <param name="filePath">The file to be converted. Full path needed.</param>
        private void ConvertExcelToXps(string filename, string tempOutputPath)
        {
            Excel.Application excel = new Excel.Application();
            excel.Visible = false;
            excel.DisplayAlerts = false;
            Excel.Workbook workbook = excel.Workbooks.Open(filename);
            workbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypeXPS, tempOutputPath);
            workbook.Close();
            excel.Quit();
            Marshal.ReleaseComObject(workbook);
            Marshal.ReleaseComObject(excel);
            excel = null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tempOutputPath"></param>
        /// <returns></returns>
        private XpsDocument MakeFixedDocument(string tempOutputPath)
        {
            return new XpsDocument(tempOutputPath, FileAccess.Read);
        }


    }
}

这是用于显示文档的ViewModel:

public FileViewerViewModel(string fileName, string exentsion)
        {
            DocumentViewerFileGenerator generator = new DocumentViewerFileGenerator();

            try
            {
                FileToDisplay = generator.GenerateDocumentForViewer(fileName, exentsion);
                FileToShow = FileToDisplay.GetFixedDocumentSequence();
                IsMainEnabled.Instance.IsWindowVisible = System.Windows.Visibility.Hidden;
            }

            catch (Exception log)
            {
                //Error handeling
            }

              /// <summary>
        /// The file that is to be shown on the view model.
        /// </summary>
        private IDocumentPaginatorSource fileToShow;
        public IDocumentPaginatorSource FileToShow
        {
            get { return fileToShow; }
            set {
                if (value == fileToShow)
                    {  return; }
                fileToShow = value;
                OnPropertyChanged();
                }
        }

        private XpsDocument FileToDisplay
        {
            get;
            set;
        }
        /// <summary>
        /// Our good, generic PropertyChanged handler. Glorious.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

         private void ClosingWindow()
        {
            if (AutoLogoutTimer.Instance.IsLogOff != true)
            {
                UnlockXPSFile(FileToDisplay);
                IsMainEnabled.Instance.IsWindowVisible = System.Windows.Visibility.Visible;
            }
        }

        private void UnlockXPSFile(XpsDocument fileToUnlock)
        {
            Package xpsPackage = PackageStore.GetPackage(fileToUnlock.Uri);
            xpsPackage.Close();
        }
 }

正如我之前所说,这是第一次运行,它运作正常。

然而,第二次在这一行创建一个新的xps文件:

 private XpsDocument MakeFixedDocument(string tempOutputPath)
 {
      return new XpsDocument(tempOutputPath, FileAccess.Read);
 }

抛出异常。

我在这里缺少什么?

谢谢。

1 个答案:

答案 0 :(得分:0)

经过一段时间的刮擦,更多的谷歌搜索和敲击键盘,我突然意识到我失踪了...

private void UnlockXPSFile(XpsDocument fileToUnlock)
{
    Package xpsPackage = PackageStore.GetPackage(fileToUnlock.Uri);
    xpsPackage.Close();
    PackageStore.RemovePackage(fileToUnlock.Uri); //This line right here
}

当我关闭软件包时,我实际上并没有将其从软件包商店中删除。因此,应用程序正在寻找相同的软件包存储来存储新的XPS文件夹,但由于它已关闭并被转储,因此它无处可去。