0

Can someone please tell me, why my excel process keeps open? In case where defaultPrinter == null becomes true, the running excel process gets terminated as expected.

I have ensured, that the last call to ReleaseComObject() is reachable, which means I can see in my log the message Releasing COM objects.

// Gets the configured default printer from the printer excel sheet 
static void GetDefaultPrinter(string printerFile, string clientname)
{
    // Create excel application object by calling constructor 
    var xlApplication = new Excel.Application();
    var xlWorkbooks = xlApplication.Workbooks;
    var xlWorkbook = xlWorkbooks.Open(Environment.GetEnvironmentVariable("TEMP") + @"\" + Environment.UserName + "@" + GetColName(clientname) + ".xls");                                              

    // Open first sheet within excel document (index start at 1, not 0) 
    Excel._Worksheet xlWorksheet = (Excel.Worksheet)xlWorkbook.Sheets["Printer<->Computer_Relations"];

    // Get used sheet bounderies 
    Excel.Range xlRange = xlWorksheet.UsedRange;

    // Get row & column count 
    int rowCount = xlRange.Rows.Count;
    int colCount = xlRange.Columns.Count;

    // Walk through first line and skip first columns for slight speed improvement
    for (int i = 7; i <= colCount; i++)
    {
        // We have found a corresponding header 
        if (xlRange.Cells[1, i].Value2.ToString().Equals(GetColName(clientname), StringComparison.CurrentCultureIgnoreCase))
        {
            WriteLog(logFile, "Found " + clientname + " at [1," + i + "]", true, true); 

            // Walking down the column 
            for (int j = 2; j < rowCount; j++)
            {
                // Find cells matching *d 
                if (xlRange.Cells[j, i] != null && xlRange.Cells[j, i].Value2 != null && (xlRange.Cells[j, i].Value2.ToString()).EndsWith("d"))
                {
                    WriteLog(logFile, "Found default printer definition at [" + j + "," + i + "] which is: " + xlRange.Cells[j, 1].Value2.ToString(), true, true); 
                    defaultPrinter = xlRange.Cells[j, 1].Value2.ToString();

                    // Jump out of first for loop
                    break; 
                }
            }

            // If no default printer has been found, exit
            if (defaultPrinter == null)
            {
                WriteLog(logFile, "No default printer found, exit!", true, true);

                // Clean up objects so excel process does not remain open
                xlWorkbook.Close();
                xlWorkbooks.Close();
                xlApplication.Quit();

                Marshal.ReleaseComObject(xlRange);
                Marshal.ReleaseComObject(xlWorkbook);
                Marshal.ReleaseComObject(xlWorkbooks);
                Marshal.ReleaseComObject(xlApplication);

                // Quit application 
                Environment.Exit(-1);
            }

            break; 
        }
    }

    // Clean up objects so excel process does not remain open
    WriteLog(logFile, "Closing excel", true, false);

    xlWorkbook.Close();
    xlWorkbooks.Close();
    xlApplication.Quit();

    WriteLog(logFile, "Releasing COM objects", true, false); 

    Marshal.ReleaseComObject(xlRange);
    Marshal.ReleaseComObject(xlWorkbook);
    Marshal.ReleaseComObject(xlWorkbooks);
    Marshal.ReleaseComObject(xlApplication);
}
Matthias Güntert
  • 4,013
  • 6
  • 41
  • 89
  • Ah yes, the everlasting mystery of the not closing excel applications. Maybe one of the answers from [this question](https://stackoverflow.com/questions/158706/how-do-i-properly-clean-up-excel-interop-objects) can help you out. – waka Oct 20 '17 at 12:23
  • 1
    The long answer is: Don't use Excel interop, you're going to have a bad time. Instead use one of the various libraries that are much better suited to this task. – DavidG Oct 20 '17 at 12:24
  • 2
    https://stackoverflow.com/a/25135685/17034 – Hans Passant Oct 20 '17 at 12:34
  • 1
    Can you workout what causes the process to remain open using traditional debugging technique such as commenting lines out &/or skipping code with the debugger. What happens if you eliminate the two lines of code when you find the default printer name - break out of that loop with defaultPrinter = null & put a break point on Environment.Exit - has the process closed. Set a dummy value in defaultPrinter without reading contents of the cell. Skip the entire of the "Walking down the column" loop. Just keep eliminating code to find the cause. – PaulF Oct 20 '17 at 13:13
  • Thanks for your answers. Calling the garbage collector in the end did the trick... @DavidG: What other libraries would you recommend (excluding OLEDB)? – Matthias Güntert Oct 20 '17 at 13:41
  • As HansPassant commented, just force the GC to work some extra rounds. If anyone cries *that's not efficient*, remind them we are talking about Excel Interop - the very definition of being inefficient. – grek40 Oct 20 '17 at 14:01
  • @Matze https://github.com/ClosedXML/ClosedXML or directly from Nuget https://www.nuget.org/packages/ClosedXML – DavidG Oct 20 '17 at 14:08

0 Answers0