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

时间:2017-03-29 12:46:19

标签: c# .net excel comobject

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进程。我已经在这里多次看过这个问题了,但是大多数的问题都没有尝试过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);
    }
}

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

1 个答案:

答案 0 :(得分:2)

要解放Office COM互操作对象,您可以按照.规则的一个版本进行操作。也就是说,当您拥有成员访问链时,您需要释放所有中间对象。

这通常意味着将您的代码拆分为其他行。

遵循该规则,您错过了一条规则。您需要保留已隐式创建的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,我希望问题能够得到解决。

相关问题