在自动化程序中挂起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
。
编辑:在您新发布的更新中,您不释放您的Row
或Range
对象。 在这些上调用FinalReleaseComObject
,我希望问题得到解决。