0

I have to do a program which reads an excel xlsx file and stores the data in to the database. This my actual simple code, I don't even take the values from the excel file, but I'm not able to kill the process. I've googled a lot and I've tried many things, but the excel process stays alive.

public void readFile(path)
        {
            try
            {
                Microsoft.Office.Interop.Excel.Application xlApp = null;
                Microsoft.Office.Interop.Excel.Workbooks workbooks = null;
                Microsoft.Office.Interop.Excel.Workbook xlWorkbook = null;
                Microsoft.Office.Interop.Excel.Worksheet xlWorksheet = null;
                Microsoft.Office.Interop.Excel.Range xlRange = null;

                xlApp = new Microsoft.Office.Interop.Excel.Application();
                workbooks = xlApp.Workbooks;
                xlWorkbook = workbooks.Open(path);
                xlWorksheet = xlWorkbook.Sheets[1];
                xlRange = xlWorksheet.UsedRange;

                //------Here is where I will read the data

                xlWorkbook.Close();
                workbooks.Close();
                xlApp.Quit();

                Marshal.FinalReleaseComObject(xlRange);
                Marshal.FinalReleaseComObject(xlWorksheet);
                Marshal.FinalReleaseComObject(xlWorkbook);
                Marshal.FinalReleaseComObject(workbooks);
                Marshal.FinalReleaseComObject(xlApp);

                xlRange = null;
                xlWorksheet = null;
                xlWorkbook = null;
                workbooks = null;
                xlApp = null;
            }
            catch (Exception e)
            {

            }
        }

And the process stays alive. I hope you can help me.

Asier Azkolain
  • 75
  • 1
  • 13

3 Answers3

1

I've tried many things... The code below seems to work.

public void readFile(path)
            {
                try
                {
                    Microsoft.Office.Interop.Excel.Application xlApp = null;
                Microsoft.Office.Interop.Excel.Workbooks workbooks = null;
                Microsoft.Office.Interop.Excel.Workbook xlWorkbook = null;
                Microsoft.Office.Interop.Excel.Sheets xlsheets = null;
                Microsoft.Office.Interop.Excel.Worksheet xlWorksheet = null;
                Microsoft.Office.Interop.Excel.Range xlRange = null;

                xlApp = new Microsoft.Office.Interop.Excel.Application();
                workbooks = xlApp.Workbooks;
                xlWorkbook = workbooks.Open(path);
                xlsheets = xlWorkbook.Sheets;
                xlWorksheet = xlsheets[1];
                xlRange = xlWorksheet.UsedRange;

                //--------------------------------------------------------------------

                xlWorkbook.Close();
                workbooks.Close();
                xlApp.Quit();

                Marshal.FinalReleaseComObject(xlRangeColumns);
                Marshal.FinalReleaseComObject(xlRangeRows);
                Marshal.FinalReleaseComObject(xlRange);
                Marshal.FinalReleaseComObject(xlWorksheet);
                Marshal.FinalReleaseComObject(xlsheets);
                Marshal.FinalReleaseComObject(xlWorkbook);
                Marshal.FinalReleaseComObject(workbooks);
                Marshal.FinalReleaseComObject(xlApp);

                xlRangeColumns = null;
                xlRangeRows = null;
                xlRange = null;
                xlWorksheet = null;
                xlsheets = null;
                xlWorkbook = null;
                workbooks = null;
                xlApp = null;
                }
                catch (Exception e)
                {

                }
            }

There are very little differences. A month ago I would tell you that both codes are the same. Can someone tell me why this code works, while the first code doesn't?

Asier Azkolain
  • 75
  • 1
  • 13
0

Try putting this at the end of your code and it will kill your excel

foreach (var process in Process.GetProcessesByName("myExcelFilename"))
{
    process.Kill();
}
Adi Mohan
  • 117
  • 1
  • 16
  • You mean killing every excel process? I can't do that because there can be more tasks (which may use excel) running at the same time in the same machine, so doing that may cause some problems... but thanks for answering! – Asier Azkolain Feb 05 '18 at 14:50
  • I'm gonna add this link here, it might help you to get the specific excel that you want to close and not all of them. https://stackoverflow.com/questions/9316141/kill-process-excel-c-sharp – Adi Mohan Feb 05 '18 at 15:04
  • Thanks for answering again. I've solved the problem by following my answer below. I forgot to mark it as the solution, sorry. Not using more than one dot per line works, I don't know why, but it works. – Asier Azkolain Feb 06 '18 at 07:27
-2

You need either to put the objects into using blocks, or put the closing statements into a finally.

Whenever your application throws an exception, it will leave the interop open. What you should do instead is put your shutdown code in a finally block, which means that code will always be run. Like so:

    public void readFile(string path)
    {
        Microsoft.Office.Interop.Excel.Application xlApp = null;
        Microsoft.Office.Interop.Excel.Workbooks workbooks = null;
        Microsoft.Office.Interop.Excel.Workbook xlWorkbook = null;
        Microsoft.Office.Interop.Excel.Worksheet xlWorksheet = null;
        Microsoft.Office.Interop.Excel.Range xlRange = null;

        try
        {


            xlApp = new Microsoft.Office.Interop.Excel.Application();
            workbooks = xlApp.Workbooks;
            xlWorkbook = workbooks.Open(path);
            xlWorksheet = xlWorkbook.Sheets[1];
            xlRange = xlWorksheet.UsedRange;

            //------Here is where I will read the data




        }
        catch (Exception e)
        {

        }
        finally
        {
            xlWorkbook?.Close();
            workbooks?.Close();
            xlApp?.Quit();

            Marshal.FinalReleaseComObject(xlRange);
            Marshal.FinalReleaseComObject(xlWorksheet);
            Marshal.FinalReleaseComObject(xlWorkbook);
            Marshal.FinalReleaseComObject(workbooks);
            Marshal.FinalReleaseComObject(xlApp);                

            xlRange = null;
            xlWorksheet = null;
            xlWorkbook = null;
            workbooks = null;
            xlApp = null;
        }
    }

Another option is not to screw around with interop and use another library, such as EPPlus (available on NuGet), to handle the reading of excel files, which would close when the program closes.