С# = Почему процессы Excel не заканчиваются?

У меня есть следующий код:

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;


    }

Фактически, он проверяет, содержит ли книга Excel специальные листы. Независимо от того, есть или нет, я хочу, чтобы процессы Excel заканчивались. Однако при каждом открытии новой книги новый процесс добавляется и никогда не удаляется?

PS. Я знаю, что там есть дублированный код... он должен быть убран в ближайшее время:)

Ответ 1

Используйте Excel.Application.Quit(), когда закончите с обработкой или тем, что вы делаете.

В вашем случае: xlApp.Quit();

UPDATE:

@Lasse V. Karlsen указал, что делать, если Excel уже работает. Ну, вот одно решение: (я не тестировал код, это просто для того, чтобы дать вам представление)

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

   // your code

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

Ответ 2

Мое решение

[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();
}

Ответ 3

Несколько дней назад я реализовал Export/Import. Я получил код ниже, когда я искал в Google, и все работает отлично.

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 { }
    }