悬挂互操作COM对象的问题

我有一个应用程序使用COM互操作来创build一个电子表格,在客户端的机器上的Excel中打开。 不过,如果我查看任务pipe理器,用户closuresExcel时EXCEL.exe进程并不总是结束。

如果我保存工作簿并以编程方式closuresExcel,则只需使用Marshal.ReleaseComObject()进行清理,但由于我依赖于手动closures程序,所以我不知道该怎么做。 有什么build议么?

Excel不能终止,直到所有的进程外对象被释放。 所以它只是隐藏其用户界面,并继续运行。 直到你的程序退出,或者你清空你所有的Excel对象引用和终结器线程运行。 退出你的程序将是一个明显的解决scheme。 或者你可以强制终结器线程运行:

 GC.Collect(); GC.WaitForPendingFinalizers(); 

ReleaseComObject()很less工作,因为它很容易忘记中介COM对象引用。 像WorkBooks [索引],这是一个你看不到的枚举器。 让GC自己作出这个决定将是更明智的select,如果你继续跑步,做事情就会发生。

可能Excel.exe仍然是打开的,因为用户在Excell应用程序的同一个实例中打开了另一个文档。 在这种情况下,你可能不应该杀死Excel.exe进程。

如果确保closures所有打开的文档,并释放所有创build的对象,那么为什么确保Excel.exe终止对您至关重要? 也许这个过程是服务于另一个应用程序,或用户?

可能有很多原因(包括Ran的),但是我看到很多MapPoint(带有COM接口的另一个Microsoft应用程序)的一个原因是您必须确保清除所有对象引用,以便垃圾收集器可以清理它们。 一个低悬挂的对象足以阻止应用程序closures并退出进程列表。

如果我打开Excel应用程序和工作簿:

 Excel.Application app = new Excel.Application(); Excel.Workbook wb = app.Workbooks.Open(...); 

然后我在finally语句(或其他适当的closures事件)中使用wb.Close()app.Quit()方法。 这将清理Exel.exe进程。 无需调用Marshall.ReleaseComObject或GC方法。