Note that there are some explanatory texts on larger screens.

plurals
  1. POc# and excel automation - ending the running instance
    primarykey
    data
    text
    <p>I'm attempting Excel automation through C#. I have followed all the instructions from Microsoft on how to go about this, but I'm still struggling to discard the final reference(s) to Excel for it to close and to enable the GC to collect it.</p> <p>A code sample follows. When I comment out the code block that contains lines similar to:</p> <pre><code>Sheet.Cells[iRowCount, 1] = data["fullname"].ToString(); </code></pre> <p>then the file saves and Excel quits. Otherwise the file saves but Excel is left running as a process. The next time this code runs it creates a new instance and they eventually build up.</p> <p>Any help is appreciated. Thanks.</p> <p>This is the barebones of my code:</p> <pre><code> Excel.Application xl = null; Excel._Workbook wBook = null; Excel._Worksheet wSheet = null; Excel.Range range = null; object m_objOpt = System.Reflection.Missing.Value; try { // open the template xl = new Excel.Application(); wBook = (Excel._Workbook)xl.Workbooks.Open(excelTemplatePath + _report.ExcelTemplate, false, false, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt); wSheet = (Excel._Worksheet)wBook.ActiveSheet; int iRowCount = 2; // enumerate and drop the values straight into the Excel file while (data.Read()) { wSheet.Cells[iRowCount, 1] = data["fullname"].ToString(); wSheet.Cells[iRowCount, 2] = data["brand"].ToString(); wSheet.Cells[iRowCount, 3] = data["agency"].ToString(); wSheet.Cells[iRowCount, 4] = data["advertiser"].ToString(); wSheet.Cells[iRowCount, 5] = data["product"].ToString(); wSheet.Cells[iRowCount, 6] = data["comment"].ToString(); wSheet.Cells[iRowCount, 7] = data["brief"].ToString(); wSheet.Cells[iRowCount, 8] = data["responseDate"].ToString(); wSheet.Cells[iRowCount, 9] = data["share"].ToString(); wSheet.Cells[iRowCount, 10] = data["status"].ToString(); wSheet.Cells[iRowCount, 11] = data["startDate"].ToString(); wSheet.Cells[iRowCount, 12] = data["value"].ToString(); iRowCount++; } DirectoryInfo saveTo = Directory.CreateDirectory(excelTemplatePath + _report.FolderGuid.ToString() + "\\"); _report.ReportLocation = saveTo.FullName + _report.ExcelTemplate; wBook.Close(true, _report.ReportLocation, m_objOpt); wBook = null; } catch (Exception ex) { LogException.HandleException(ex); } finally { NAR(wSheet); if (wBook != null) wBook.Close(false, m_objOpt, m_objOpt); NAR(wBook); xl.Quit(); NAR(xl); GC.Collect(); } private void NAR(object o) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(o); } catch { } finally { o = null; } } </code></pre> <hr> <h2>Update</h2> <p>No matter what I try, the 'clean' method or the 'ugly' method (see answers below), the excel instance still hangs around as soon as this line is hit:</p> <pre><code>wSheet.Cells[iRowCount, 1] = data["fullname"].ToString(); </code></pre> <p>If I comment that line out (and the other similar ones below it, obviously) the Excel app exits gracefully. As soon as one line per above is uncommented, Excel sticks around.</p> <p>I think I'm going to have to check if there's a running instance prior to assigning the xl variable and hook into that instead. I forgot to mention that this is a windows service, but that shouldn't matter, should it?</p> <hr>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. COYou won't get the "ugly" method to work until you get it exactly right. There are no half measures, because as long as there's *any* COM reference left un-released, Excel will stick around. Please post your "ugly" code so that we can spot the bug - I can guarantee there will be one. Note that in the code as posted, you're setting wb to null in the main block, and thus *preventing* it from being properly released in your finally block. But that's only one problem (we've discussed the Workbooks object and the Range objects below).
      singulars
    2. COI have to mention (though it's not particularly relevant to the discussion) that your NAR method is probably not doing what you think. The line "o = null;" in the finally block is setting the local parameter variable o to null, but that has no effect on the variable in the calling method. So after NAR(xl), the variable xl will NOT be null! Having said that, there should be no need to set the variables to null anyway - unless you're superstitious about it.
      singulars
    3. COI just noticed your mention of it running as a Windows service. It shouldn't have any bearing on the issue at hand, but let me give you a heads-up. My application (or part of it) runs a Windows service, and works fine under Windows XP or Windows 2003 Server, but I'm having problems with it on Vista and flat-out cannot get it to run under Windows Server 2008. Just thought I'd mention that in case your development machine is XP and your target platform is Vista/2008...
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload