views:

116

answers:

4

Hi, I've got unit test with this code:

  Excel.Application objExcel = new Excel.Application();
            Excel.Workbook objWorkbook = (Excel.Workbook)(objExcel.Workbooks._Open(@"D:\Selenium\wszystkieSeba2.xls", true,
            false, Missing.Value, Missing.Value, Missing.Value,
            Missing.Value, Missing.Value, Missing.Value,
            Missing.Value, Missing.Value, Missing.Value,
            Missing.Value));


            Excel.Worksheet ws = (Excel.Worksheet)objWorkbook.Sheets[1];
            Excel.Range r = ws.get_Range("A1", "I2575");
            DateTime dt = DateTime.Now;
            Excel.Range cellData = null;
            Excel.Range cellKwota = null;
            string cellValueData = null;
            string cellValueKwota = null;
            double dataTransakcji = 0;
            string dzien = null;
            string miesiac = null;
            int nrOperacji = 1;
            int wierszPoczatkowy = 11;
            int pozostało = 526;

            cellData = r.Cells[wierszPoczatkowy, 1] as Excel.Range;
            cellKwota = r.Cells[wierszPoczatkowy, 6] as Excel.Range;


            if ((cellData != null) && (cellKwota != null))
            {

                object valData = cellData.Value2;
                object valKwota = cellKwota.Value2;


                if ((valData != null) && (valKwota != null))
                {
                    cellValueData = valData.ToString();
                   dataTransakcji = Convert.ToDouble(cellValueData);
                   Console.WriteLine("data transakcji to: " + dataTransakcji);
                    dt = DateTime.FromOADate((double)dataTransakcji);
                   dzien = dt.Day.ToString();
                   miesiac = dt.Month.ToString();


                    cellValueKwota = valKwota.ToString();


                }
  }

                       r.Cells[wierszPoczatkowy, 8] = "ok";
            objWorkbook.Save();



            objWorkbook.Close(true, @"C:\Documents and Settings\Administrator\Pulpit\Selenium\wszystkieSeba2.xls", true);
                objExcel.Quit();

Why after finish test I'm still having excel in process (it does'nt close)

And : is there something I can improve to better perfomance ??

Excel 2007 and .net 3.5

+2  A: 

I use a code segment like this to forcefully close it:

    public void DisposeExcelInstance()
    {
        //oXL.DisplayAlerts = false;
        //oWB.Close(null, null, null);
        //oXL.Quit();


        //oWB.Close(null, null, null);
        //oXL.Quit();
        ///KNG - CLEANUP code
        oXL.DisplayAlerts = false;
        oWB.Close(null, null, null);
        oXL.Workbooks.Close();
        oXL.Quit();
        if (oResizeRange != null)
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oResizeRange);
        if (oSheet != null) 
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet);
        if (oWB != null)
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);
        if (oXL != null)
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
        oSheet = null;
        oWB = null;
        oXL = null;
        GC.Collect(); // force final cleanup!

    }
Kangkan
+1, may I suggest changing to FinalReleaseComObject in order to be more generic in case someone uses code for something else.
AMissico
If all references to Excel objects are released, then Excel will close. The problem is it's too easy to miss one. In the above code you've missed on - the line "oXL.Workbooks.Close()" implicitly creates a reference to "oXL.Workbooks" which isn't released. I believe that calling GC.Collect() twice at the end will pick up on the ones you missed.
Joe
Thanks for the nice analysis. I shall update.
Kangkan
A: 

In addition to Kangkan's answer, you can also try to use an existing Excel instance (if there is still an unclosed instance running):

        try {
            objExcel = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
        } catch (Exception) {
            if (objExcel == null) {
                objExcel = new Excel.Application();
            }
        }
Prutswonder
I don't understand...why create new excel process ? In next running test, or what ?
If you have an unclosed Excel instance, it will be re-used using the sample above. If there is no unclosed Excel instance running, then a new instance will be created.
Prutswonder
A: 

Maybe ur reference count is off: http://support.microsoft.com/kb/317109

ja