Darren Young
Darren Young

Reputation: 11090

C# = Why are Excel processes not ending?

I have the following code:

private bool IsMousetrapFile(string path)
    {

        logger.Log(validateFileMessage + path);

        Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        Excel.Workbooks workbooks = xlApp.Workbooks;
        Excel.Workbook xlWorkBook = workbooks.Open(path, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        Excel.Sheets worksheets = (Excel.Sheets)xlWorkBook.Worksheets;
        Excel.Worksheet ws = null;


        foreach (string sheet in expectedWorksheets)
        {

            try
            {

                ws = (Excel.Worksheet)worksheets.get_Item(sheet);
                logger.Log(validMousetrapFileMessage + path);
            }
            catch
            {
                logger.Log(validateSheetError + sheet + ": " + path);
                if (ws != null)
                    Marshal.ReleaseComObject(ws);
                Marshal.ReleaseComObject(worksheets);
                Marshal.ReleaseComObject(xlWorkBook);
                Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(xlApp);

                return false;

            }

        }

        if (ws != null)
            Marshal.ReleaseComObject(ws);
        Marshal.ReleaseComObject(worksheets);
        Marshal.ReleaseComObject(xlWorkBook);
        Marshal.ReleaseComObject(workbooks);
        Marshal.ReleaseComObject(xlApp);

        return true;


    }

Effectively, it checks if an Excel workbook contains specific sheets. Irrespective of whether there is or isn't, I want to Excel processes to end. However, each time a new workbook is open, a new process is added, and never deleted?

PS. I know there is duplicate code there....it shall be tidied soon :)

Upvotes: 11

Views: 11998

Answers (3)

Loart
Loart

Reputation: 71

My solution

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

private void GenerateExcel()
{
    var excel = new Microsoft.Office.Interop.Excel.Application();
    int id;
    // Find the Process Id
    GetWindowThreadProcessId(excel.Hwnd, out id);
    Process excelProcess = Process.GetProcessById(id);

try
            {
                // Your code
}
finally
{
    excel.Quit();

    // Kill him !
    excelProcess.Kill();
}

Upvotes: 3

HABJAN
HABJAN

Reputation: 9328

Use Excel.Application.Quit() when you are done with processing or whatever you are doing.

In your case: xlApp.Quit();

UPDATE:

@Lasse V. Karlsen pointed out what to do if Excel was already running. Well, here is one solution: ( i did not test the code, this is just to give you an idea )

private void TestMethod()
{
   bool excelWasRunning = System.Diagnostics.Process.GetProcessesByName("excel").Length > 0;

   // your code

   if (!excelWasRunning)
   { 
       xlApp.Quit();
   }
}

Upvotes: 10

simplyaarti
simplyaarti

Reputation: 253

Few days back I have implemented Export/Import. I got below code from somewhere when I have searched on Google and it works fine.

ExportToExcel()
{
    try
    {
        //your code
    }
   catch (Exception ex)
        {

        }
        finally
        {
            TryQuitExcel(Application_object);
        }
}
private static void TryQuitExcel(Microsoft.Office.Interop.Excel.Application  application)
        {
            try
            {
                if (application != null &&
                  application.Workbooks != null &&
                  application.Workbooks.Count < 2)
                {
                    application.DisplayAlerts = false;
                    application.Quit();
                    Kill(application.Hwnd);
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(application);
                    application = null;
                }
            }
            catch
            {
                /// Excel may have been closed via Windows Task Manager.
                /// Skip the close.
            }
        }


 private static void Kill(int hwnd)
    {
        int excelPID = 0;
        int handle = hwnd;
        GetWindowThreadProcessId(handle, ref excelPID);

        Process process = null;
        try
        {
            process = Process.GetProcessById(excelPID);

            //
            // If we found a matching Excel proceess with no main window
            // associated main window, kill it.
            //
            if (process != null)
            {
                if (process.ProcessName.ToUpper() == "EXCEL" && !process.HasExited)
                    process.Kill();
            }
        }
        catch { }
    }

Upvotes: 1

Related Questions