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

Hanging Excel.exe process in automated program

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 objects,但是即使上面的代码仍然让我在程序完成 运行 后挂起 EXCEL.EXE 个进程宁。我已经在这里多次看到这个问题,但是大多数提问者都没有尝试过 ReleaseComObject() 方法,但是这对我来说没有任何解决方法。

编辑:这是我在删除 header

后用来读取 table 的代码
  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编辑了 post 顶部的新代码。我仍然有一个挥之不去的 object(即使我 运行 这个过程多次)。调用 Gc.Collect() 可行,但作为一个相对的新手,我认为最好避免使用如此强大的东西。

要释放 Office COM 互操作对象,您可以按照 'one release per . rule' 进行。也就是说,当您拥有成员访问链时,您需要释放所有中间对象。

这通常意味着将您的代码拆分成额外的行。

按照这条规则,你少了一个。您需要保留隐式创建的 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,我希望问题得到解决。