Search code examples
c#excelcom

Closing Excel process after creating using Excel COM


The code below creates a corrupted file/read-only excel csv file so i cant open the file to write data inside. I need to read the data from the csv file then save it into an excel file to plat a graph. May I know what's wrong with the code? Cause everytime i want to delete the file that is generated, it's still running in the process even if i closed it. I have to go to Task Manager everytime to force close the process then only I can delete the file.

I have tried literally every solutions provided in this link but nothing solves my problem. I wanted to try using but idk what changes I have to make so that's the only thing I haven't tried till now.

Excel.WorkBook xlWorkBook;

...

public void createXMLFile()
        {
            Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

            if (xlApp == null)
            {
                MessageBox.Show("Excel is not properly installed!!");
                return;
            }

            object misValue = System.Reflection.Missing.Value;

            xlWorkBook = xlApp.Workbooks.Add(misValue);
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

            xlWorkSheet.Cells[1, 1] = "Stroke";
            xlWorkSheet.Cells[1, 2] = "Force";

             xlWorkBook.SaveAs(filePath, Excel.XlFileFormat.xlWorkbookNormal, AccessMode: Excel.XlSaveAsAccessMode.xlExclusive);
            xlWorkBook.Close(true, misValue, misValue);
            xlApp.Quit();

            Marshal.ReleaseComObject(xlWorkSheet);
            Marshal.ReleaseComObject(xlWorkBook);
            Marshal.ReleaseComObject(xlApp);

            MessageBox.Show("Excel file created , you can find the file     
D:\\Work\\ExtractData\\DataCharts");
}

Solution

  • Try this approach…

    Microsoft.Office.Interop.Excel.Application xlApp = null;
    Microsoft.Office.Interop.Excel.Workbook xlWorkBook = null;
    try {
      // code that works with excel…
    }
    catch (Exception ex) {
      MessageBox.Show("Excel Error " + ex.Message);
    }
    finally {
      if (xlWorkBook != null) {
        xlWorkBook.Close();
        Marshal.ReleaseComObject(xlWorkBook);
      }
      if (xlApp != null) {
        xlApp.Quit();
        Marshal.ReleaseComObject(xlApp);
      }
      //GC.Collect();
    }
    

    Edit… per OP comment…

    I am guessing that you may be misinterpreting what the task manager is posting. For starters, .NET uses a Garbage Collector to manage its unused memory. And if you want to “immediately” get rid of the multiplying instances of Excel that appear to be lingering in the Task Manger is to call the .NET Garbage Collector directly like…

    GC.Collect();
    

    HOWEVER,… I DO NOT RECOMMEND THIS.

    If you exit the application, then ALL the instances will get released. If the app continues to run, then usually at least one instance of Excel will remain. However, when the application is running... Often the Garbage Collector will not release this memory from the app if it has plenty of memory already, which makes sense.

    So, even though it still appears in the task manager, if push comes to shove and something NEEDS memory, it will release it. Which is the case here. Granted there may be many instances of Excel running… if you run the code many times over without exiting the application… the Excel apps will "eventually" get released. In my tests, usually after about 10-20 apps were running, they would all get released and it would go down to one or two Excel instances. Then it would grow again. This is the job of the Garbage Collector.

    Calling the Garbage Collector's Collect code above will release the app “immediately” as you want, however, I would say be careful. It is not recommended that you do this. So, I say pick your own poison here.