1の目的のためにドキュメントビューアでファイルを開くために使用されるアプリケーションがあります:ユーザーがファイルを変更できないようにする、2:開いているファイルを追跡する、彼らはオープンしています。ObjectDisposed 2番目のXPSエクスポートで例外が発生しました
つまり、私が選択したファイル(Word DocsまたはExcel Workbook)は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);
}
例外がスローされます。
私はここで何が欠けていますか?
ありがとうございます。
デバッガを使用して、xpsパッケージを処理するコード内で唯一の場所と思われる 'UnlockXPSFile'を呼び出す方法を確認してください。 – Evk
@Evkそれが呼び出される唯一の時間は 'ClosingWindow()'メソッドです。新しいファイルが選択されると、viewmodel、view、およびxpsオブジェクト全体がインスタンス化されます。それが私がとても混乱している理由です。 –