0

I've read a lot of different threads and articles on stack and other websites, but I'm still having some issues cleaning up EXCEL Interop COM processes when I finish with my application.

I've created myself a little class which allows me to load in worksheets, modify cells, rename work sheets and to also format different cells.

Here are the variables i'm using and the constructor.

Excel.Application _excelApp = null;
Excel.Workbook _excelBook = null;
Excel.Worksheet _excelSheet = null;
Excel.Range _excelRange = null;

When I create my class object, the constructor does this:

FileName = excelFileName; // Just used to reference a creation name
_excelApp = new Excel.Application();

Now, the next thing I do is load in a sheet for modification:

 public bool LoadExcelSheet(string location, string file)
 {
      string startupPath = Environment.CurrentDirectory; // Get the path where the software is held

      _excelBook = _excelApp.Workbooks.Open(Path.Combine(startupPath, location, file)); // Load in the workbook

      _excelSheet = _excelBook.Worksheets[1]; // sets the excel sheet to the init worksheet

      sheetName = _excelSheet.Name; // set the sheetname variable

      isSheetLoaded = CheckIfWorkBookExists(); // a little check to see if the workbook exists - yes shows it has been loaded, if a no then it hasn't

      return isSheetLoaded;

}

The next thing I do in my software is run through a function that allows me to set any cell (by an int ID defining the row and column) and modify it with a given string:

public void ModifyCell(int row, int column, string data)
{
     int[] cellRange = new int[2] { row, column };

     _excelRange = _excelSheet.Cells;
     _excelRange.set_Item(row, column, data);

     dataFormat.Add(cellRange); // this adds each row and column into a list which holds every modified cell for easy formatting

     Marshal.ReleaseComObject(_excelRange); // Releases the COM object
}

So, when I finish my excel operations I the call my cleanup function:

public void Cleanup()
{
    if (_excelApp != null) // if a cleanup hasn't been initiated
    {
                    // set all the com objects to null, this is so the GC can clean them up
                    _excelRange = null;
                    _excelSheet = null;
                    _excelBook = null;
                    _excelApp = null;
                }

                // These garbage collectors will free any unused memory - more specifically the EXCEL.EXE*32 process that LOVES to stay, forever and ever. Like a mother inlaw...
                GC.GetTotalMemory(false);
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.GetTotalMemory(true);  
    }
}

I run the cleanup when I finish modifying the excel sheet, and also when I close the program just to double check that everything has been cleaned up. Though, that darn EXCEL.EXE*32 is still there!

Johnathan Brown
  • 713
  • 12
  • 35
  • 1
    IIRC, the workbook should be [closed](https://msdn.microsoft.com/EN-US/library/office/ff838613.aspx). – chris Mar 03 '15 at 15:24
  • 1
    I'm not sure if it's still true but I think that it is.... You simply cannot expect the managed code side to clean up COM side object by just calling something similar to your Cleanup method. Go to CodeProject or Stackoverflow and look up the "Proper way to use Dispose" or "IDispose".... This is one of the reasons I can't stand to use Interop classes on MSFT platform... It shows the negligence of MSFT not willing to keep the COM and managed side seamless. – JWP Mar 03 '15 at 15:24
  • @chris Thanks, that worked. I also closed the app when finishing. Can't believe I missed that. – Johnathan Brown Mar 03 '15 at 15:28
  • @JohnPeters What's is MSFT? – Johnathan Brown Mar 03 '15 at 15:28
  • Ah, right... Aha embarrassing. – Johnathan Brown Mar 03 '15 at 15:34

1 Answers1

1

With Excel (any Office application, really) interop, you have to be very diligent when managing resources. You should always use resources for as short a time as possible and release them as soon as you don't need them anymore. You should also explicityly release all objects to make sure they're cleaned up properly.

Here's an older answer of mine with more detail: COM object excel interop clean up

If you follow the steps outlined in the answer, you won't have stray Excel instances sticking around.

Community
  • 1
  • 1
xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • Thanks for the answer xxbbcc. I also followed Chris's comment which stopped the stray process. – Johnathan Brown Mar 03 '15 at 15:27
  • Fantastic answer given, I do love learning new things! I shall be changing the way I use my COM objects and try to understand exactly what your COM Wrapper does! Thanks again. – Johnathan Brown Mar 03 '15 at 15:33