0

after writing something in a cell of an existing excel file, the excel process in the background didn't close. If i comment out the section with worksheet.Cells[1,1]=2 then the excel process will disappear like expected.

Thx in advance for help.

Here is my code:

                Excel.Application exelApp = new Excel.Application();
                var workbooks = exelApp.Workbooks;
                Excel.Workbook workbook = null;

                workbook = workbooks.Open(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, Type.Missing, Type.Missing);


                var worksheets = workbook.Worksheets;
                Excel.Worksheet worksheet = (Excel.Worksheet)worksheets.get_Item("Einzelliste");

                //worksheet.Cells[1, 1] = 2;

                workbook.Close(true, Type.Missing, Type.Missing);
                workbooks.Close();
                exelApp.Quit();

                ReleaseObject(worksheet);                    
                ReleaseObject(worksheets);                                        
                ReleaseObject(workbook);                    
                ReleaseObject(workbooks);                                       
                ReleaseObject(exelApp);

                worksheet = null;
                worksheets = null;
                workbook = null;
                workbooks = null;
                exelApp = null;

    private static void ReleaseObject(object theObject)
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(theObject);
    }

Edit: According to the suggestion from Mark:

                var range =worksheet.get_Range("A1");
                range.Value = 1; ReleaseObject(range);

In contradiction to some suggestions that this post is a duplucated question: I have to say that it's not because all the objects were released correctly and there is no use of "double dots" in the source code. The suggested calls of Garbage Collector do not solve the problem either.

Benjamin Martin
  • 576
  • 1
  • 8
  • 27
  • possible duplicate of [How to properly clean up Excel interop objects](http://stackoverflow.com/q/158706/2140173) –  Mar 11 '15 at 15:29
  • `//worksheet.Cells[1, 1] = 2;` what if you changed it to `//worksheet.Cells[1, 1].Value = 2;` – MethodMan Mar 11 '15 at 15:29
  • @ Michal: I have read the post already, but it doesn't contain my problem. – Benjamin Martin Mar 11 '15 at 15:32
  • @MethodMan: There is no definition for Value. – Benjamin Martin Mar 11 '15 at 15:32
  • I also notice that you are not `Activating` the worksheet.. which may or may not be needed.. question, when you step through the code, what happens when you step into the code and past this line `worksheet.Cells[1, 1] = 2;` when you uncomment it ..? does it raise and error or just hangup.. what happens when you use the Quick Watch to inspect `worksheet.Cells[1, 1];` – MethodMan Mar 11 '15 at 15:38
  • @MethodMan: Nothing happened when i passed the line worksheet.Cells[1,1]=2; The application didnt hang and the file was saved correctly. When i used Quick Watch i couldn't see anything special but some Reflection.TargetInvocationExeption with some COM properties. But i think it doesn't matter. – Benjamin Martin Mar 11 '15 at 15:54
  • @BenjaminMartin so does this cause an actual problem with your running process..? even though you are calling the Marshal.ReleaseComObject method, I am thinking that the reference to it is being handled properly however the `Garbage Collector` does not remove it from the TaskManager immediately as you are probably expecting.. can you clarify on if this is truly causing an issue especially in regards to if you wanted to open the saved excel spread sheet after saving.. – MethodMan Mar 11 '15 at 15:59
  • Instead of Interop, consider using a library like EPPlus and the Open XML SDK to read/update/generate `xlsx` files directly, without using Excel at all. – Panagiotis Kanavos Mar 12 '15 at 09:37
  • @Pnagiotis Kanavos: Yeah you are right, but using Open XML SDK has it's flaws especially in manipulating tables and charts. EPPlus is not compatible with Excel 2013 and furthermore the complexity of using Open XML SDK is tremendous. – Benjamin Martin Mar 12 '15 at 09:44

2 Answers2

0

Try using the Range object to get access to cells or cell before manipulating it. Then make sure you release the COM Object referencing the range. You also need to arrange your calls so that you release the COM Object right after you use it. Try also save the changes in the Excel document, Excel might not be closing because it is waiting for a user response to save the file.

Additionally (although not required by the OP), never loop across the cells of Excel. Prepare your data on an array of objects either for cells in a row or cells in a column. Use array of arrays for a grid. Then use the Range object to set the values.

Mark Menchavez
  • 1,651
  • 12
  • 15
  • the OP is correctly releasing the ComObject in the `ReleaseObject` method – MethodMan Mar 11 '15 at 15:34
  • @MethodMan, there is a hidden reference to the cells[1, 1] which has not been released. – Mark Menchavez Mar 11 '15 at 15:48
  • I am thinking that there is an Indexing issue but I can't tell that is why I am waiting on the OP to respond with what the data is when debugging and using the `QuickWatch` to validate what the data is in `cells[1,1]` if any . – MethodMan Mar 11 '15 at 15:51
0

Based on information provide in this link, I think the cause of the problem may lie in the following line of code.

  Excel.Worksheet worksheet = (Excel.Worksheet)worksheets.get_Item("Einzelliste");

Just a guess, because it doesn't follow the rule in the link exactly, but I wonder if the cast does something funny with COM object.

The critical part of the link was:

your problem is the line.

Dim wkBook As Workbook = xlApp.Workbooks.Open("C:\test.xls

because .net needs wrapper to call com objects it really turns into

Dim wkBook As Workbook dim tmp as WorkBooks tmp = xlApp.Workbooks wkBook = tmp.Open("C:\test.xls

the tmp variable has a com ref that will not be released until its garabage collected. the rule you should use is never use 2 dots with com objects. alway create a tmp, and call ReleaseComObject() on the tmps.

Of course, your code doesn't have the exact same stuff, but I wonder if the cast might be causing some strange behavior behind the scenes.

Owen Ivory
  • 244
  • 1
  • 9