Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code cause Excel to not close properly?

Tags:

c#

excel

Why does this line of code cause Excel not to exit?

Excel.Range range = (Excel.Range)ws.Cells[1,1];

If it's because of the casting, then wouldn't this code cause the same problem?

Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;

I've tried. But this works. Excel will close.

If I use this code. Excel closes.

Excel.Range range = ws.get_Range("A1","A1");

So what's the difference? Yes I know there's like a million of "How to close Excel properly" threads. But since this is a question and not an answer, I decided to ask a new one instead of asking in other people's question.

Here's my code. But of course there's another codes in between. I'm just commenting out everything and slowly trying out which lines causes Excel to not close. I realise that even without using Garbage collector, Excel still closes. I do not want to use a sledgehammer to close Excel.

Thanks.

Excel.Application objExcel = new Excel.Application();
Excel.Workbooks wbs = objExcel.Workbooks;
Excel.Workbook wb = wbs.Open(saveFileDialog1.FileName, 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.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;
//Excel.Range range = (Excel.Range)ws.Cells[1,1];
Excel.Range range = ws.get_Range("A1","A1");

FinalReleaseAnyComObject(range);
FinalReleaseAnyComObject(ws);
wb.Close(Type.Missing, Type.Missing, Type.Missing);
FinalReleaseAnyComObject(wb);
FinalReleaseAnyComObject(wbs);
objExcel.Quit();
FinalReleaseAnyComObject(objExcel);

Currently I've tried until objExcel, wbs, wb and ws. These 4 objects does not cause a problem.

private static void FinalReleaseAnyComObject(object o)
{
    Marshal.FinalReleaseComObject(o);
    o = null;
}

I realise that you cannot reuse the variable as well.

Excel.Range range = ws.get_Range("A1","G1");
range = ws.get_Range("A1", "A1");

This will cause Excel not to close properly too. Instead, use this.

Excel.Range range = ws.get_Range("A1","G1");
FinalReleaseAnyComObject(range);
range = ws.get_Range("A1", "A1");
like image 912
user607455 Avatar asked Feb 11 '11 01:02

user607455


People also ask

How do you force an Excel spreadsheet to close?

Both CTRL + W and CTRL + F4 will close the current workbook. If you would like to close all workbooks that are open, as well as Excel itself, the shortcut that will achieve this is Alt + F4.

Why does it take Excel so long to close?

You may need to repair Office, or there may be a hidden workbook starting up with the application that is taking a long time to close. Click View>Unhide to see if anything is there. My second option for you is to try running it in a safe mode. Then kindly try to uninstall and reinstall it.


1 Answers

There's a hidden Range interface pointer that you can't see, the Cells property returns it. You then apply the indexer expression to it, dereferencing the default Item property of that Range. To get another Range.

This is why it is such a bad, bad idea to try to manage COM interface pointers yourself. Trust the garbage collector to always get it right. GC.Collect() and GC.WaitForPendingFinalizers() if you really, really want to make it quit on demand. Be sure to read this answer to understand why this doesn't always work as expected when you debug your program.

like image 51
Hans Passant Avatar answered Sep 22 '22 08:09

Hans Passant