我有一个C#程序,它打开一个Excel文件,读取一个单元格,关闭文件,然后退出Excel。不幸的是,Windows任务管理器仍然显示正在运行的Excel.exe进程。我已经阅读了关于这个问题的每篇文章,并尝试了几乎所有的解决方案。 。 。并仍然有同样的问题。我相信其中一个COM对象没有被释放,从而挂起了这个过程。但是,我也相信我一直非常小心地实例化Excel对象(没有双“。”)并释放它们。
如果我删除“a = xlCells [1,1] .Value”行,那么每个东西都会释放,Excel会在Application实例的FinalReleaseComObject之后干净地死掉。为什么这个赋值会创建COM对象或干扰它们?
Excel.Application xlApp = null;
Excel.Workbooks xlWorkbooks = null;
Excel.Workbook xlWorkbook = null;
Excel.Sheets xlSheets = null;
Excel.Worksheet xlWorksheet = null;
Excel.Range xlCells = null;
string inputFile = @"C:\Temp\test.xlsx";
string a;
xlApp = new Excel.Application();
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
xlWorkbooks = xlApp.Workbooks;
xlWorkbook = xlWorkbooks.Open(inputFile);
xlSheets = xlWorkbook.Sheets;
xlWorksheet = xlSheets[1];
xlCells = xlWorksheet.Cells;
a = xlCells[1,1].Value;
Marshal.FinalReleaseComObject(xlCells);
xlCells = null;
Marshal.FinalReleaseComObject(xlWorksheet);
xlWorksheet = null;
Marshal.FinalReleaseComObject(xlSheets);
xlSheets = null;
xlWorkbook.Close(false, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(xlWorkbook);
xlWorkbook = null;
xlWorkbooks.Close();
Marshal.FinalReleaseComObject(xlWorkbooks);
xlWorkbooks = null;
xlApp.Quit();
Marshal.FinalReleaseComObject(xlApp);
xlApp = null;
答案 0 :(得分:0)
我会做两处修改。首先,由于Sheets项目可以是工作表或图表工作表,因此最好使用As
进行投射并检查null
。其次,如果您只想获得带有字母数字地址的范围,get_Range()
方法效果很好。否则,如果您想按行和列索引进行操作,请按照@Daneau的评论进行操作。
xlWorksheet = xlSheets[1] as Excel.Worksheet;
if(xlWorksheet != null)
{
xlCells = xlWorksheet.get_Range("A1");
a = xlCells[1,1].Value;
Marshal.FinalReleaseComObject(xlCells);
xlCells = null;
Marshal.FinalReleaseComObject(xlWorksheet);
xlWorksheet = null;
}
答案 1 :(得分:0)
我更改了代码并添加了虚拟Range对象。
Range tmpCell = xlCell[1,1];
a = tmpCell.Value;
Marshal.ReleaseComObject(tmpCell);
我的问题消失了。非常感谢,Daneau!
真正的例程有几个循环,正在评估单元格。我认为使用tmpCell为每个新的单元格赋值都可以正常工作,然后在最后发布tmpCell。那失败了。在每个新的tmpCell赋值给xlCell [x,y]之前,我不得不释放tmpCell。这有效,但肯定很麻烦。很难相信没有更好的方法来管理它或跟踪各种COM对象。