I'm using the Excel interop for C# and all the methods to dispose of it exactly as described in many different places and no matter which method I use to dispose of the objects there is still an Excel.exe process running after the method finishes and everything should be finished and released. The existence of the process wouldn't bother me so much except you cannot open Excel without first closing my app which happens to terminate the Excel process at the same time.
Without resorting to actually figuring out which Excel processes have a parent process of my process and terminating them, I don't know what else to do.
Here is the current test method I'm using which should by all means work and releae:
private bool FillExcelFileWithDataTest()
{
string sPath = "C:\\Some.xls";
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range oRange = null;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
var xlWorkbooks = xlApp.Workbooks;
xlWorkBook = xlWorkbooks.Open(sPath);
var xlWorksheets = xlWorkBook.Worksheets;
xlWorkSheet = xlWorksheets.get_Item(1);
oRange = xlWorkSheet.Cells[1, 1];
oRange.Value = "Test";
oRange = xlWorkSheet.Cells[1, 1];
oRange.Copy();
oRange = xlWorkSheet.Cells[2, 1];
oRange.PasteSpecial(Excel.XlPasteType.xlPasteFormats);
if (oRange != null)
{
releaseObject(oRange);
}
releaseObject(xlWorkSheet);
releaseObject(xlWorksheets);
xlWorkBook.Save();
xlWorkBook.Close(true, misValue, misValue);
releaseObject(xlWorkBook);
releaseObject(xlWorkbooks);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorksheets);
releaseObject(xlWorkBook);
releaseObject(xlWorkbooks);
releaseObject(xlApp);
GC.Collect();
GC.WaitForPendingFinalizers();
xlWorkSheet = null;
xlWorksheets = null;
xlWorkBook = null;
xlWorkbooks = null;
xlApp = null;
return true;
}
private void releaseObject(object obj)
{
try
{
// Do not catch an exception from this.
// You may want to remove these guards depending on
// what you think the semantics should be.
if (obj != null)
{
while(Marshal.FinalReleaseComObject(obj) > 0)
{ }
}
// Since passed "by ref" this assingment will be useful
// (It was not useful in the original, and neither was the
// GC.Collect.)
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
//GC.Collect();
}
}
What am I doing wrong?