0

I have a function to read an Excel, then workbook and sheet. But the Excel thread never finish. I tried every solution i found around here but didn't work.

Excel thread stack on task manager, and at moment, my application crash because of Excel stop working.

    public static object[,] ReadFile(string filepath, string sheetname)
    {
        Application xlApp = null;
        Workbooks wks = null;
        Workbook wb = null;
        object[,] values = null;
        try
        {
            xlApp = new ApplicationClass();
            wks = xlApp.Workbooks;
            wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
            Worksheet sh = (Worksheet)wb.Worksheets.get_Item(sheetname);

            values = sh.UsedRange.Value2 as object[,];


            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sh);
            sh = null;

        }
        catch (Exception ex)
        {
            throw new Exception(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
        }
        finally
        {

            if (wb != null)
            {

                wb.Close(false);
                Marshal.FinalReleaseComObject(wb);
                wb = null;
            }

            if (wks != null)
            {
                wks.Close();
                Marshal.FinalReleaseComObject(wks);
                wks = null;
            }

            if (xlApp != null)
            {
                // Close Excel.
                xlApp.Quit();
                Marshal.FinalReleaseComObject(xlApp);
                xlApp = null;
            }


        }

        return values;
    }

Maybe i don't do things in the right order, or maybe i understood wrong the COM object problem.

CathalMF
  • 9,705
  • 6
  • 70
  • 106
Delta
  • 49
  • 1
  • 7
  • In which line does your app crash? – Gusman May 03 '16 at 09:37
  • I have to read a lot of Excel file. So the code launch an Excel each time on "xlApp = new ApplicationClass();". I thought the "xlApp.Quit();Marshal.FinalReleaseComObject(xlApp);xlApp = null;" was enough to cose the Excel. But the Excel never close. So the application crash because , at a moment, i have near 20 EXCEL.EXE process running in background. – Delta May 03 '16 at 09:49
  • FinalReleaseComObject should not be necessary. You are using a .net wrapper for excel. What happens if you remove the FinalReleaseComObject? – Uwe Hafner May 03 '16 at 09:54
  • Ok, try to use ReleaseComObject instead of FInalReleaseComObject, this problem has been exposed more times in S.O.: http://stackoverflow.com/questions/17367411/cannot-close-excel-exe-after-interop-process, http://stackoverflow.com/questions/3937181/when-to-use-releasecomobject-vs-finalreleasecomobject – Gusman May 03 '16 at 09:54
  • As i said, i've already tried all i've seen on SO. ReleaseComObject didn't work and i tried the 'not-two-dot' xlApp = new ApplicationClass(); wks = xlApp.Workbooks; wb = wks.Open(filepath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing); sheets = wb.Worksheets; sh = (Worksheet)sheets.get_Item(sheetname); It' didn't work too... – Delta May 03 '16 at 12:19

2 Answers2

1

I had same issue I used below code to specifically kill the process

[DllImport("user32.dll")]
    static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

    Process GetExcelProcess(Excel.Application excelApp)
    {
        int id;
        GetWindowThreadProcessId(excelApp.Hwnd, out id);
        return Process.GetProcessById(id);
    }

This method GetExcelProcesswill give you the exact process which you can kill manually. It will remove Excel.exe from task manager.

AddyProg
  • 2,960
  • 13
  • 59
  • 110
1

In my understanding it should not be necessary to explicitly release the com objects if you use a .NET wrapper object like excel interop. If excel still exists then I would look for errors in handling as something might be left over.
In the sample below the excel process stops already when it comes to the first console.ReadLine. In case it does not immediately stop try to hit enter to start a GC.

The following works for me and excel is stopped.
I used:
.NET Framework 4.5.2
Microsoft.Office.Interop.Excel 1.7.0.0
Excel 2010
Windows 7

using System;
using Microsoft.Office.Interop.Excel;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Go");
            var t = ReadFile(@"<filename>", "<sheetname>");
            Console.WriteLine("1");
            Console.ReadLine();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Console.ReadLine();
        }


        public static object[,] ReadFile(string filepath, string sheetname)
        {
            Application xlApp = null;
            Workbooks wks = null;
            Workbook wb = null;
            object[,] values = null;
            try
            {
                xlApp = new Application();
                wks = xlApp.Workbooks;
                wb = wks.Open(filepath);
                Worksheet sh = (Worksheet)wb.Worksheets.get_Item(sheetname);

                values = sh.UsedRange.Value2 as object[,];

                //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sh);
                //sh = null;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(string.Format("Sheet \"{0}\" does not exist in the Excel file", sheetname));
            }
            finally
            {

                if (wb != null)
                {

                    wb.Close(false);
                    //Marshal.FinalReleaseComObject(wb);
                    wb = null;
                }

                if (wks != null)
                {
                    wks.Close();
                    //Marshal.FinalReleaseComObject(wks);
                    wks = null;
                }

                if (xlApp != null)
                {
                    // Close Excel.
                    xlApp.Quit();
                    //Marshal.FinalReleaseComObject(xlApp);
                    xlApp = null;
                }


            }

            return values;
        }
    }

}

As a comment to the linked stackoverflow question on not using two dot commands. This sample worked on my machine also with two dot commands (opening a workbook). It did not make a difference. Excel was released and the process was closed. The excel sheet used for testing was a standard sheet with 3 fields filled in with numbers.

Uwe Hafner
  • 4,889
  • 2
  • 27
  • 44