Josh Robinson's WebLog

How to fully close Excel when using COM Interop

One of the applications that I wrote about a year ago allows a user to upload a native Excel document to the server from the web app, then opens Excel to perform work on the file.  Before I go any further, let me say that I do not think this is the smartest thing to do since there are variables that you can't control, but the app is deployed on an intranet and we have full control over the server and it was needed so we did it.

At any rate, the basic premise is as follows: the server opens Excel XP (since then upgraded to 2003) through a COM Interop (using the PIA), parses the specific information from the worksheet then closes the Excel Application.  The parsed data is returned to the calling method which continues on its merry way.
  One thing that always bothered me was that no matter how hard we tried to close the Excel Application object (we used objXLApp.Quit()) , the Excel.exe process was always still running on the server when you viewed the running processes in the task manager.  The reason that we didn't pursue it any more at the time was because the app would automatically re-use the open object the next time the Excel object was needed, or if multiple users hit it at the same time, multiple Excel processes would be opened (and left open).

Today I finally had time to dig a little deeper and figure out how to fully close a COM Interop object using the ReleaseComObject(object) method found in the System.Runtime.InteropServices.Marshal namespace.  Most articles dealing with Excel COM Interop don't mention this little trick, instead throwing in a quick objExcelApp.Quit() and leaving it at that.  Here is a snippet showing some sample code on how to close an instance of Excel that you opened earlier in the code:

Imports System.Runtime.InteropServices.Marshal

'Close running excel app
xlApp.Quit()

'Use the Com Object interop marshall to release the excel object
ReleaseComObject(xlApp)

xlApp = Nothing

'force a garbage collection
System.GC.Collect()

  If there is an better way, please let me know, but this definitely closes the Excel process on the server.

Comments

Josh Robinson said:

Greg, glad to see that you agree and came to basically the same conclusion. There is not as much info out there as you would expect on using the Excel COM Interop, so thought others mind find the info useful. That's really ironic that we both posted independently on the same day! (I promise I didn't see your post first :)
# March 29, 2004 10:15 PM

css said:

I haven't run into this problem. I was using the PIA's too and just did .Quit() in C#. The only time Excel wouldn't close properly is if there was an exception somewhere else in the program.
# March 30, 2004 12:27 AM

Bernd R. said:

Instead of just calling GC.Collect(), try this:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

# June 18, 2004 3:01 AM

Greg (not the same Greg) said:

This technique is not working for me, although I've been over it many times. I suspect that I may have left references to range objects open, and that these references are preventing the Excel COM object from closing. I believe that I have to call ReleaseComObject on the Range objects as well.

# December 20, 2007 6:31 PM

Daniel said:

I had similar problems with this and the

ReleaseComobject

GC.Collect

GC.Wait

GC.Collect

worked great on IIS5.

(Note: You need to configure DCOM).

However on IIS6 & I would guess 7 the problem returned with Excel.exe processes not being spanked.

# February 7, 2008 10:16 AM

TD said:

Does not work at all for me.

Times like this I have absolutely no respect for Microsoft for letting problems like this linger.

# May 21, 2008 4:03 PM

Chetan said:

I am also trying to release object but still excel process is running in background.

Its working find when i run this application from visual studio but when i create setup of that application and try to run from web browser it wont work.

any solution??????

# May 28, 2008 4:15 AM

Pete said:

Yep.

This recipe does NOT work at all.

(Excel 2003).

Sometimes I feel really mad at MS for being so incompetent.

# June 30, 2008 2:47 PM

Pablo said:

This should work...

using System.Diagnostics;

           foreach (Process process in Process.GetProcessesByName("Excel"))

           {

               process.Kill();

           }

# January 29, 2010 9:27 AM

Roy S said:

@Above: That works but if the user has excel open while doing that, it would also close excel (without even asking to save your progress in it).

# February 8, 2010 5:34 PM

joseph said:

This is what I used

xclapp.Quit()

           System.Runtime.InteropServices.Marshal.ReleaseComObject(xclapp)

           xclapp = Nothing

           xclbook = Nothing

           xclsheet = Nothing

           System.GC.Collect()

# July 21, 2010 9:02 AM

Jerry said:

Hi all, I've tried Josh's method and they do work

properly! but still I have something to say, if you

met an exception then you don't need to use Quit();

and you can use ReleaseComObject() only;e.g.

ReleaseComObject(xlApp);

xlApp = null;

System.GC.Collect();

However if you don't meet an exception, you must use

Quit(); before using the ReleaseComObject();

xlApp.Quit();

// OR xlApp.Workbook.close(false,false,false);

ReleaseComObject(xlApp);

xlApp = null;

System.GC.Collect();

Excel process should be killed by now.

# December 9, 2010 9:32 PM

cheersmate said:

Hello guys,

I have faced the same issue but resolved it using try, catch and finally. I have put all the excel closing stuff in finally and the error has been resolved.

finally

       {

           mWSheet1 = null;

           mWSheet2 = null;

           mWorkBook = null;

           oXL.Quit();

           oXL = null;

           GC.WaitForPendingFinalizers();

           GC.Collect();

           GC.WaitForPendingFinalizers();

           GC.Collect();

       }

Cheers !

# April 7, 2011 4:25 AM

Hash said:

Awesome..Works like a charm !!!

Thanks Cheersmate !!!!

# November 8, 2011 4:01 PM

Ken said:

Thanks for the tip on closing out Excel completely.  Fixed my problem.

# November 20, 2011 5:35 PM

Tim said:

One additional thought.  

I found that if I called GC outside the method that opened the xlapp, it would close, this particularly if more than one xlapp was opened.  

# January 17, 2012 9:23 AM

carmen said:

Hi Tim,

Thanks a lot! It works.

Carmen

# July 20, 2012 12:06 AM

Sajjad Abdullah said:

Thanks a lot dear all....It worked for me really....thanks again

# August 28, 2012 1:17 AM