关闭Excel应用程序的正确方法

时间:2012-03-06 10:21:00

标签: c# com excel-interop

我正在编写一个应用程序,它使用以下代码访问Excel文件:

RBTApplication = new Excel.Application();
RBTWorkbooks = RBTApplication.Workbooks;
RBTWorkbook = RBTApplication.Workbooks.Open(
    RBTDataSet.Instance.FilePath, 0, true, 5, "", "", true,
    Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
    "\t", true, false, 0, true, 1, 0 );
RBTWorksheet = (Excel.Worksheet)RBTWorkbook.Worksheets.get_Item( 1 );
RBTRange = RBTWorksheet.UsedRange;

在我加载了我需要的数据后,我尝试用这段代码关闭Excel应用程序:

RBTWorkbook.Close();
RBTApplication.Quit();
RBTWorksheet.ReleaseComObject();
RBTWorkbook.ReleaseComObject();
RBTWorkbooks.ReleaseComObject();
RBTApplication.ReleaseComObject();

我的问题是EXCEL.EXE进程仍在运行。 杀死所有Excel进程的简单解决方案听起来不太好,因为我的进程可能是同时使用的许多电子表格之一。这个也会影响打开新的Excel电子表格 - 每个电子表格都是只读的,直到我不会杀死这个过程。

那么......如何正确关闭这个应用程序或者杀死这个特定的进程(有没有办法从COM对象中获取PID?)。我想我找到了一个(还没试过) - 在打开新的ExcellApp之前和之后获取excell进程列表,比较列表(得到差异),杀死知道其PID的特定进程。但是这个解决方案似乎不是从我的应用程序中处理COM对象和其他应用程序的正确方法。

1 个答案:

答案 0 :(得分:4)

您没有发布所有COM对象。

例如:

RBTApplication.Workbooks.Open

将实例化Workbooks对象,如下:

RBTWorkbook.Worksheets.get_Item

而是使用您已创建的Worksheets对象:

RBTWorkbooks = ...
...
RBTWorkbooks.Open(...)
RBTWorkbooks.get_Item(...)

如果您的互操作要求很简单,并且互操作代码已本地化,您可以小心确保释放所引用的所有COM对象,理想情况下使用try / finally确保即使抛出异常也会释放它们。

但是,您或维护程序员很容易忘记一个,所以您可能希望查看强制垃圾收集,例如see the answers to this question.