{"id":82,"date":"2005-06-29T01:52:17","date_gmt":"2005-06-29T00:52:17","guid":{"rendered":"http:\/\/www.craigmurphy.com\/blog\/?p=82"},"modified":"2008-10-20T22:14:57","modified_gmt":"2008-10-20T21:14:57","slug":"excel-interop-killing-excelexe","status":"publish","type":"post","link":"https:\/\/www.craigmurphy.com\/blog\/?p=82","title":{"rendered":"Excel Interop &#8211; killing Excel.exe"},"content":{"rendered":"<p><a href=\"http:\/\/www.scottishdevelopers.com\/modules\/newbb\/viewtopic.php?viewmode=thread&#038;topic_id=641&#038;forum=2100\">This<\/a> posting over at <a href=\"http:\/\/www.scottishdevelopers.com\">ScottishDevelopers<\/a> got me thinking, especially since I&#8217;ve used Excel and Word from a number of Delphi applications over the last eight years.  I have come across this problem in the past (Win32), so I thought it should be fairly easy to chase.<\/p>\n<p>After a bit of research, <a href=\"http:\/\/www.codeproject.com\/csharp\/Package.asp\">The Code Project<\/a> suggested that the Excel process be killed off through code:<\/p>\n<pre name=\"code\" class=\"csharp\">\r\nProcess[] pProcess; \r\npProcess = System.Diagnostics.Process.GetProcessesByName(\"Excel\");\r\npProcess[0].Kill();\r\n<\/pre>\n<p>Well, that would work, but it might kill off the wrong instance, or kill off the user&#8217;s precious &#8216;expenses&#8217; spreadsheet instead of the one we created.  <\/p>\n<p>To help me trace the problem, I used the following code:<\/p>\n<pre name=\"code\" class=\"csharp\">\r\nusing System.Diagnostics;\r\nusing System.Runtime.InteropServices;\r\n\r\nExcel.Application\texcelApp = null;\r\nExcel.Workbook\texcelWorkbook = null;\r\nExcel.Sheets\texcelSheets = null;\r\nExcel.Worksheet\texcelWorksheet = null;\r\nExcel.Workbooks\texcelWorkbooks = null;\r\n\r\nprivate void button3_Click(object sender, System.EventArgs e)\r\n{\r\n  excelApp                 = new Excel.ApplicationClass();\r\n  excelApp.Visible  = true;\r\n  excelWorkbooks   = excelApp.Workbooks;\r\n  excelWorkbook = excelWorkbooks.Add(System.Reflection.Missing.Value);\r\n  excelSheets = excelWorkbook.Worksheets;\r\n  excelWorksheet = (Excel.Worksheet)   excelSheets.get_Item(1);\r\n  excelWorksheet.Cells[1,1] = \"42\";\r\n}\r\n\r\nprivate void button4_Click(object sender, System.EventArgs e)\r\n{\r\n  excelWorkbook.Close (false, System.Reflection.Missing.Value,System.Reflection.Missing.Value) ; \r\n\r\n  excelWorkbooks.Close();\r\n  excelApp.Quit();\r\n\r\n  Marshal.ReleaseComObject(excelWorksheet);\r\n  Marshal.ReleaseComObject(excelSheets);\r\n  Marshal.ReleaseComObject(excelWorkbooks);\r\n  Marshal.ReleaseComObject(excelWorkbook);\r\n  Marshal.ReleaseComObject(excelApp);\r\n\r\n  excelWorksheet = null;\r\n  excelSheets = null;\r\n  excelWorkbooks = null;\r\n  excelWorkbook = null;\r\n  excelApp = null;\r\n\r\n  GC.GetTotalMemory(false);\r\n  GC.Collect();\r\n  GC.WaitForPendingFinalizers();\r\n  GC.Collect();\r\n  GC.GetTotalMemory(true);\r\n}\r\n<\/pre>\n<p>This code creates an Excel application, populates it, then lets us close it. Invoking the button3 code creates it, button4 removes it. <\/p>\n<p>Now, without the calls to the garbage collector, excel.exe hung around if the code behind button3, button4, button3, button4 is invoked.<\/p>\n<p>In the short-term, I would suggest adding the additional calls to the <strong>garbage collector<\/strong> (although, and <a href=\"http:\/\/support.microsoft.com\/default.aspx?scid=kb;en-us;317109\">this <\/a>confirms it, memory reclamation is not guaranteed).  It&#8217;s time to read up on the garbage collector and COM Interop.<\/p>\n<p><em>I used Visual Studio 2003 and Office 2003 to test this.<\/em><\/p>\n<p>Technorati Tags: <a href=\"http:\/\/technorati.com\/tag\/Excel\" rel=\"tag\">Excel<\/a>, <a href=\"http:\/\/technorati.com\/tag\/InterOp\" rel=\"tag\">InterOp<\/a>, <a href=\"http:\/\/technorati.com\/tag\/Kill+Process\" rel=\"tag\">Kill Process<\/a>, <a href=\"http:\/\/technorati.com\/tag\/C%23\" rel=\"tag\">C#<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a recent posting over at ScottishDevelopers, it was noted that sometimes Excel.exe doesn&#8217;t disappear from the Task Manager&#8230;even if you think you&#8217;ve cleaned up after yourself&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[136,133,134,135],"class_list":["post-82","post","type-post","status-publish","format-standard","hentry","category-net","tag-c","tag-excel","tag-interop","tag-kill-process"],"_links":{"self":[{"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/82","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=82"}],"version-history":[{"count":0,"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/82\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.craigmurphy.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}