在自动化程序中挂起Excel.exe进程

var tempFileName = file.Replace(".xlsx", "_Temp.xlsx"); Application excelApp = new Application(); Workbooks books = excelApp.Workbooks; Workbook excelFile = books.Open(file); Sheets sheets = excelFile.Worksheets; var app = excelApp.Application; DeleteRows(sheets, 3); excelFile.SaveAs(tempFileName); excelFile.Close(); books.Close(); app.Quit(); excelApp.Quit(); Marshal.FinalReleaseComObject(sheets); Marshal.ReleaseComObject(excelFile); Marshal.ReleaseComObject(books); Marshal.FinalReleaseComObject(excelApp); sheets = null; excelFile = null; excelApp = null; books = null; 

我正在尝试处理我的excel对象,但是即使上面的代码仍然让我在程序运行完成后挂起EXCEL.EXE进程。 我已经在这里看到过这个问题了很多次,但是大多数asker都没有尝试过ReleaseComObject ReleaseComObject()方法,但是这并没有为我解决任何问题。

编辑:这是我用来删除标题后读取表的代码

  System.Data.DataTable schemaTable = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); DataRow schemaRow = schemaTable.Rows[0]; string sheet = schemaRow["TABLE_NAME"].ToString(); if (!sheet.EndsWith("_")) { string query = "SELECT * FROM [Daily Payment$]"; OleDbDataAdapter daexcel = new OleDbDataAdapter(query, excelConnection); dtexcel.Locale = CultureInfo.CurrentCulture; daexcel.Fill(dtexcel); var reader = dtexcel.CreateDataReader(); 

这里是DeleteRows的代码:

 void DeleteRows(Sheets sheets, int n) { foreach (Worksheet workSheet in sheets) { Range range = workSheet.get_Range("A1", "A" + n); Range row = range.EntireRow; row.Delete(XlDirection.xlUp); Marshal.ReleaseComObject(workSheet); } } 

最终编辑:我已经在post顶部重新发布了新的代码。 我仍然得到一个挥之不去的对象(即使我运行的过程多次)。 调用Gc.Collect()的作品,但作为一个相对的新手,我认为这是最好的,以避免如此强大的东西。

为了释放Office COM互操作对象,您可以按“一个版本”进行操作. 规则'。 也就是说,当你有一连串的成员访问,你需要释放所有的中间对象。

这通常意味着将您的代码分解成更多行。

遵循这个规则,你错过了一个。 您需要保留对您隐式创build的Workbooks对象的句柄。

 Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application(); Workbooks books = excelApp.Workbooks; Workbook excelFile = books.Open(file); DeleteRows(excelFile, 3); 

那么你需要打电话给:

 Marshal.ReleaseComObject(books); 

最后。

如果没有这个,你也可以尝试调用:

 books.Close() 

在退出Excel之前。 而过度使用,你可以改变你所有的ReleaseComObject调用FinalReleaseComObject

编辑:在您新发布的更新中,您不释放您的RowRange对象。 在这些上调用FinalReleaseComObject ,我希望问题得到解决。