1

I am attempting to open an xls file, read in several rows of data, form a custom list from data and then close the excel sheet. This is what I have:

InitializeWorkbook(Path);
List<Custom> list = new List<Custom>();

Worksheet wkSht = (Worksheet)workBk.Worksheets[3];

if (wkSht.Name.Equals("Sht3", StringComparison.OrdinalIgnoreCase))
{
    Range PartNumRange = wkSht.get_Range("A:A", System.Reflection.Missing.Value);
    Range RevRange = wkSht.get_Range("C:C", System.Reflection.Missing.Value);
    Range SwRange = wkSht.get_Range("L:L", System.Reflection.Missing.Value);
    Range NomenRange = wkSht.get_Range("M:M", System.Reflection.Missing.Value);

    // Start at Row 6
    int i = 6;
    object Num = (PartNumRange[i, 1] as Range).Text;
    object Nomen = (NomenRange[i, 1] as Range).Text;
    object Sw = (SwRange[i, 1] as Range).Text;
    object SwRev = (RevRange[i, 1] as Range).Text;

    while (!string.IsNullOrEmpty(Num.ToString()) || !string.IsNullOrEmpty(Nomen.ToString()) || !string.IsNullOrEmpty(Sw.ToString()) || !string.IsNullOrEmpty(SwRev.ToString()))
    {
        if (!string.IsNullOrEmpty(Nomen.ToString()) && !string.IsNullOrEmpty(Sw.ToString()) && !string.IsNullOrEmpty(SwRev.ToString())
        {
            Custom item = new Custom();

            item.PartNumber = (PartNumRange[i, 1] as Range).Text.ToString();
            item.Nomenclature = (NomenRange[i, 1] as Range).Text.ToString();
            item.SwNumber = (SwRange[i, 1] as Range).Text.ToString();
            item.SwRevision = (RevRange[i, 1] as Range).Text.ToString();

            list.Add(item);
        }

        i++;
        Num = (PartNumRange[i, 1] as Range).Text;
        Nomen = (NomenRange[i, 1] as Range).Text;
        Sw = (SwRange[i, 1] as Range).Text;
        SwRev = (RevRange[i, 1] as Range).Text;
    }

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

    Marshal.ReleaseComObject(PartNumRange);
    Marshal.ReleaseComObject(RevRange);
    Marshal.ReleaseComObject(SwRange);
    Marshal.ReleaseComObject(NomenRange);

    Marshal.ReleaseComObject(wkSht);
    workBk.Close(false, System.Reflection.Missing.Value, false);
    Marshal.ReleaseComObject(workBk);

    Marshal.ReleaseComObject(ExcelWorkSheets);

    ExcelApp.Quit();
    Marshal.ReleaseComObject(ExcelApp);

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

I dont know why but Excel is not closing after I finish executing. Only when the program exits does Excel exit. I have tried all sorts of combinations and have avoided the two dot rule but still a no go. Any ideas on what I'm missing?

EDIT: Calling ExcelApp.Quit closes both ExcelApp and ExcelWorksheets.

1
  • Believe me, I walked the Excel automation way (two dot rule, marshal release and all), then I discovered Flexcel, and I never looked back. You might consider this solution? Commented Oct 2, 2012 at 15:49

3 Answers 3

1

You might want to take a look at this post: How do I properly clean up Excel interop objects?

There's a lot of in-depth discussions about handling COM objects in C# that you might find helpful. Worth a read.

Sign up to request clarification or add additional context in comments.

2 Comments

The question linked above is very good. In fact, an answer there maybe the same problem: workBk.Worksheets[3] is creating a wrapper around the Worksheets COM Object.
Rich, that was it. There was a few other things I had noticed in the API I was using (that had InitializeWorkbook and CloseExcel methods in it) to control Excel that were also doing the same thing (like ExcelApp.Workbook.Open()) so I had fixed those and everything is working now. Thanks!
0

You also need to call close on

  • ExcelWorkSheets
  • ExcelApp

Calling Marshal.ReleaseComObject disposes the runtime callable wrapper, but leaves the application itself still alive and kicking.

1 Comment

ExcelApp.Quit closes ExcelApp and ExcelWorkSheets, sorry forgot to mention that.
0

You can try with this code - it's work fine

while (Marshal.ReleaseComObject(YourRange) > 0) 
{}

while (Marshal.ReleaseComObject(YourWorkSheet) > 0) 
{}

while (Marshal.ReleaseComObject(YourWorkBook) > 0) 
{}

YourApplication.quit()

while (Marshal.ReleaseComObject(YourApplication) > 0) 
{}

2 Comments

I just tried this and it Excel is still running. I have updated the OP with an update.
@dangerisgo add while to your code in order to clean all instance, i had the same problem, i resolved with while;;;; But you can delete GC.Collect(); GC.WaitForPendingFinalizers();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.