5

I have a problem releasing Excel from Task Manager after I create an Excel file, Save and Close it from C#.

I use the following code to create the Excel instance:

 Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

Microsoft.Office.Interop.Excel.Workbook workbook = xlApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];

I then populate my worksheet:

worksheet.Cells[1, 1] = "Test";
worksheet.Cells[1, 2] = "Test";
worksheet.Cells[1, 3] = "Test";
worksheet.Cells[1, 4] = "Test";

After that I save the workbook:

workbook.SaveAs(filePath);

Then close it:

workbook.Close(false, false);

and then quit Excel:

xlApp.Quit();

But after I do this Excel still appears in the Task Manager!!?!?

Any idea why this doesn't get closed after I call xlApp.Quit()?

Thanks in advance.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user1131661
  • 229
  • 3
  • 8
  • 19

3 Answers3

6

Maybe you could try dropping Interop and using EPPlus to create/modify Excel files. It's very easy and doesn't relay on having Office on computer.

But if you really want to go with Interop then this might help (I've been using it on my code to make sure everything is disposed properly as I had to create 800+ excel files in few minutes):

        workBook.Close(true, filePathTarget, Missing.Value);
        app.DisplayAlerts = true;
        app.Quit();
        Release(workSheet2);
        Release(workSheet1);
        Release(workBook);
        Release(workBooks);
        Release(app);
        workSheet2 = null;
        workSheet1 = null;
        workBook = null;
        workBooks = null;
        app = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();

Where:

 private static void Release(object obj) {
        // Errors are ignored per Microsoft's suggestion for this type of function:
        // http://support.microsoft.com/default.aspx/kb/317109
        try {
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
        } catch {
        }
    }

But i really urge you to try to use EPPlus if you deal with XLSX files only. It works great, it's fast and efficient and doesn't relay on Microsoft Office being installed. After working with it for an hour I dropped Interop 5 minutes later...

MadBoy
  • 10,824
  • 24
  • 95
  • 156
  • Thanks for mentioning EPPlus. It looks fantastic. Not relaying on MS Office being installed is a major advantage. – AlefSin Apr 18 '12 at 15:40
0

You need to set the xlApp variable to null to release the COM reference. It is probably COM that is holding the instance open because the reference count is not zero.

xlApp = null;
mgnoonan
  • 7,060
  • 5
  • 24
  • 27
  • This might not be enough. I remember playing with Interop and it was crazy. I even had to force GC to come in and collect everything. – MadBoy Apr 18 '12 at 15:30
  • I'm no fan of Interop either, but that was the question. – mgnoonan Apr 18 '12 at 15:31
  • I understand but that won't work :-) you need to play a bit more to kick out Excel :-) Check my answer and see what I was doing to actually get it kicked out... – MadBoy Apr 18 '12 at 15:33
0

I used a process.kill method which seems unclean but it works very well.

dim xlHWND= Xlapp.Hwnd
Dim proc = Process.GetProcessesByName("excel")
For i As Integer = 0 To proc.Count - 1
     If proc(i).MainWindowHandle = xlHWND Then
          proc(i).Kill()
     End If
Next