未释放 Excel 互操作对象
本文关键字:对象 互操作 Excel 释放 | 更新日期: 2023-09-27 17:55:44
我正在使用以下方法。执行此代码块后,我通过检查任务管理器发现Microsoft Excel仍在后台运行。
编辑:只有一个Microsoft Excel后台进程保持活动状态。我只是添加这个,因为当我第一次开始使用 Excel 和互操作 COM 对象时,有时许多进程会在函数完成执行后保持运行。
如何确保在执行当前函数后 Excel 不会在后台运行?
我用全局范围声明这些变量,因为有几个函数最终需要它们:
private Excel.Application xls = null;
private Excel.Workbooks workBooks = null;
private Excel.Workbook workBook = null;
private Excel.Sheets sheets = null;
private Excel.Worksheet workSheet = null;
此方法用于检查给定工作簿中是否存在工作表:
private bool sheetExists(string searchString)
{
xls = new Excel.Application();
workBooks = xls.Workbooks;
workBook = workBooks.Open(workbookPath); // <- Where the workbook is saved
sheets = workBook.Sheets;
bool isFound = false;
foreach (Excel.Worksheet sheet in sheets)
{
// Check the name of the current sheet
if (sheet.Name == searchString)
{
Marshal.ReleaseComObject(sheet);
isFound = true;
break;
}
Marshal.ReleaseComObject(sheet);
}
cleanUp(true, xls, workBooks, workBook, sheets);
return isFound;
}
此函数用于释放 COM 对象:
private void cleanUp(bool saveTrueFalse, params object[] comObjects)
{
workBook.Close(saveTrueFalse);
xls.Application.Quit();
xls.Quit();
foreach (object o in comObjects)
{
Marshal.ReleaseComObject(o);
}
workSheet = null;
sheets = null;
workBook = null;
workBooks = null;
xls = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
我希望看到一个合适的解决方案,但这个黑客是我让它工作的唯一方法。似乎互操作库根本不擅长在被告知时关闭进程。如果在线程中运行,则会为每个线程启动进程。我会在启动后通过按名称扫描进程并跟踪新进程来跟踪进程 ID。我在服务器上执行此操作,因此我知道所有进程都是互操作启动的,而不是由实际用户启动的。在我完成逻辑后,我会启动一个计时器,每隔一分钟左右就会尝试终止该过程。最终它会关闭它。我还有一些代码可以在启动时杀死任何 Excel 进程,以防它们在上次应用程序运行时未正确终止。
如果您需要按名称或 id 杀死进程的示例代码,请告诉我。我没有现成的,或者快速的SO搜索应该会带来一些好的样本。