在Office PIA应用程序中,对Office App的管理不容忽视。
在正常情况下,程序launch office app以后,通过interop的COM组件进行文档操作,然后保存、关闭office app。但这个过程在出错的情况下,office app可能还没有关闭,并且依然占用着所操作的文件,这当然不是我们期望看到的。
以ExcelApp这个类为例,看看我在里面是怎么考虑的。以下贴出一些相关的程序片断:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Threading;
using Excel = Microsoft.Office.Interop.Excel;
/// <summary>
/// Excel application interop class.
/// </summary>
public class ExcelApp : IDisposable
{
#region Const definition
/// <summary>Microsoft Excel application process name.</summary>
private const string ExcelProcessName = "EXCEL";
#endregion
#region Private variables
/// <summary>Original Excel Application processes before launching new Excel process.</summary>
private Process[] originalExcelProcess = null;
#endregion
#region Initializations and Finalizations
/// <summary>
/// Initializes a new instance of the ExcelApp class.
/// </summary>
public ExcelApp()
{
// ......
this.originalExcelProcess = Process.GetProcessesByName(ExcelProcessName);
}
/// <summary>
/// Finalizes an instance of the ExcelApp class.
/// </summary>
~ExcelApp()
{
this.Dispose(false);
}
#endregion
#region Private methods for IDisposable
/// <summary>
/// Dispose method
/// </summary>
/// <param name="disposing">Disposing status</param>
protected void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
if (disposing)
{
// Cleanup managed resource
this.Close();
}
// Cleanup un-managed resource
// ...
this.CleanUnhandledAppInstance();
this.disposed = true;
}
#endregion
#region Private Excel methods - Application
/// <summary>
/// clean up unhandled Excel application instances.
/// </summary>
private void CleanUnhandledAppInstance()
{
Process[] currentExcelProcess = Process.GetProcessesByName(ExcelProcessName);
if (currentExcelProcess == null || currentExcelProcess.Length == 0)
{
return;
}
List<Process> killList = null;
if (this.originalExcelProcess == null || this.originalExcelProcess.Length == 0)
{
killList = new List<Process>(currentExcelProcess);
}
else
{
killList = new List<Process>();
bool isExists;
foreach (Process process in currentExcelProcess)
{
isExists = false;
foreach (Process originalProcess in this.originalExcelProcess)
{
if (originalProcess.Id == process.Id)
{
isExists = true;
break;
}
}
if (!isExists)
{
killList.Add(process);
}
}
}
if (killList != null || killList.Count > 0)
{
foreach (Process process in killList)
{
process.Kill();
}
}
}
#endregion
}
当考虑到某个操作可能会意外终止时:
#region Public Excel methods - Workbook
/// <summary>
/// Creates the excel doc.
/// </summary>
/// <param name="fileName">the excel doc filename</param>
public void CreateWorkbook(string fileName)
{
try
{
this.CurrentWorkbook = this.Application.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
this.LatestWorksheet = this.CurrentWorkbook.Sheets[1] as Excel.Worksheet;
this.CurrentWorksheet = this.LatestWorksheet;
string fullPath = this.GetActualFullPath(fileName);
this.LatestWorksheet.SaveAs(
fullPath,
this.currentFileFormat,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Excel.XlSaveAsAccessMode.xlExclusive,
Type.Missing /* 28591 */ /* ISO 8859-1 Latin 1; Western European (ISO) */,
Type.Missing,
Type.Missing);
}
catch (Exception ex)
{
this.Dispose();
throw ex;
}
}
#endregion