1

currently I have the misfortune to write C# code to read stuff from an Excel file. I'm using the Nuget Excel Interop to accomplish this.

I try to follow the advices given in this great blog post here: https://www.add-in-express.com/creating-addins-blog/2013/11/05/release-excel-com-objects/

But even when putting everything into a variable that gets released in the end, when I start accessing cells (type Range), the Excel process just wont die.

Hence my question: When I do this:

Application excel = new Application();
_toBeReleased.Add(excel);
DoStuff(excel);

...

void DoStuff(Application excel2)
{

...

Does excel2 also need to be released? Because the reference was given byval into the method?

Dee J. Doena
  • 1,631
  • 3
  • 16
  • 26
  • Excel is a pain in the fluff, i had to do a lot of what felt like very unnecessary work to clear out excel as you might expect. Including forced garbage runs, Im not using the nuget package, I was using straight office interop, but id imagine its not dissimilar. – BugFinder Sep 12 '19 at 10:12
  • 1
    https://stackoverflow.com/a/25135685/17034 – Hans Passant Sep 12 '19 at 10:15
  • You just have one reference (a RCW) to the native COM object: https://learn.microsoft.com/en-us/dotnet/standard/native-interop/runtime-callable-wrapper . Have you tried to just call excel.Quit() ? – Simon Mourier Sep 12 '19 at 10:40
  • _"...when I start accessing cells..."_ - by the way, whilst normally true there is only one RCW per COM object, that rule `does not apply to items in a COM collection` exposed by the RCW. Whenever you iterate a RCW "COM collection", the [RCW representation of the COM collection returns a new RCW each time you fetch an item from the collection irrespective of whether it is the same index](https://stackoverflow.com/a/56712047/585968) violating a few COM rules c++ developers are accustomed to in the process. –  Sep 12 '19 at 10:46

1 Answers1

-1

I don't believe that passing a COM object to another method - excel2 in your example - would complicate any form of releasing objects you may need to perform. Passing a class to a method passes a reference to the object and as long as your method runs synchronously then it should return without any persisting reference to excel2.

It should be likely that if you wait long enough the garbage collector will run and clear up your running instance of Excel. As waiting for this is going to be a problem you can force it to run from your code:

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

I have previously called Marshal.ReleaseComObject(excel) prior to calling the garbage collector, but I understand this isn't actually necessary.

Alternative Option (only supporting .xslx)

This isn't a direct answer to your question but if you can restrict your development to only support the newer (2007 / 2010) .xlsx format - rather than the older .xls format, then you wouldn't need to use Excel directly at all.

There is a great NuGet package called EPPlus which would allow you to create or edit a .xlsx file directly with no dependency on Excel the application.

I appreciate this is of no use if you must support the older .xls format.

Rob Kite
  • 395
  • 1
  • 11
  • Could you please let me know why this answer is being down voted? I'm more than happy to learn something new if my answer is wrong. – Rob Kite Sep 18 '19 at 15:44