Excel process does not close

I have this C # program that never closes the Excel process. It basically finds the number of instances of a row in Excel format. I tried all kinds of things, but it does not work. There is a form that calls this method, but it should not change why the process does not close. I look at the offers of Hans Passan, but no one works.

EDIT: I tried everything that was mentioned, and it still won't be closed. Here is my updated code. EDIT: Tried the whole Process.Kill (), and it works, but it seems to crack something that should just work.

public class CompareHelper { // Define Variables Excel.Application excelApp = null; Excel.Workbooks wkbks = null; Excel.Workbook wkbk = null; Excel.Worksheet wksht = null; Dictionary<String, int> map = new Dictionary<String, int>(); // Compare columns public void GetCounts(string startrow, string endrow, string columnsin, System.Windows.Forms.TextBox results, string excelFile) { results.Text = ""; try { // Create an instance of Microsoft Excel and make it invisible excelApp = new Excel.Application(); excelApp.Visible = false; // open a Workbook and get the active Worksheet wkbks = excelApp.Workbooks; wkbk = wkbks.Open(excelFile, Type.Missing, true); wksht = wkbk.ActiveSheet; ... } catch { throw; } finally { GC.Collect(); GC.WaitForPendingFinalizers(); if (wksht != null) { //wksht.Delete(); Marshal.FinalReleaseComObject(wksht); wksht = null; } if (wkbks != null) { //wkbks.Close(); Marshal.FinalReleaseComObject(wkbks); wkbks = null; } if (wkbk != null) { excelApp.DisplayAlerts = false; wkbk.Close(false, Type.Missing, Type.Missing); Marshal.FinalReleaseComObject(wkbk); wkbk = null; } if (excelApp != null) { excelApp.Quit(); Marshal.FinalReleaseComObject(excelApp); excelApp = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); /* Process[] processes = Process.GetProcessesByName("EXCEL"); foreach (Process p in processes) { p.Kill(); } */ } } } 
+7
c # excel winforms
source share
3 answers

Here's an interesting knowledge base about how office applications stay open after a .NET application disconnects from them.

Office application does not close after automation from the Visual Studio.NET client

Code examples - everything is in the link (vb.net sorry). It basically shows how to properly set up and tear down an office application so that it closes when you are done with it.

System.Runtime.InteropServices.Marshal.FinalReleaseComObject where the magic happens.

EDIT: You need to call FinalReleaseComObject for each excel object you created.

 if (excelWorkSheet1 != null) { Marshal.FinalReleaseComObject(excelWorkSheet1); excelWorkSheet1 = null; } if (excelWorkbook != null) { Marshal.FinalReleaseComObject(excelWorkbook); excelWorkbook = null; } if (excelApp != null) { Marshal.FinalReleaseComObject(excelApp); excelApp = null; } 
+3
source share

DotNet only frees a COM object after all descriptors have been released. What I do is comment on everything, and then add the part. See if it releases Excel. If it does not comply with the following rules. When it is released, add more code until it is released again.

1) When you create Excel variables, set all values ​​to null (this avoids the errors caused by the error)

2) Do not reuse variables without releasing them first Marshal.FinalReleaseComObject

3) Do not double the point (ab = z) . dotNet creates a temporary variable that will not be released.

 c = ab; c = z; Marshal.FinalReleaseComObject(c); 

4) Release all excel variables. The faster the better.

5) Set it back to NULL.

Set the culture to "en-US". There is a bug that breaks Excel with some cultures. This ensures that it will not.

Here is an idea of ​​how your code should be structured:

  thisThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); InteropExcel.Application excelApp = null; InteropExcel.Workbooks wkbks = null; InteropExcel.Workbook wkbk = null; try { excelApp = new InteropExcel.Application(); wkbks = excelApp.Workbooks; wkbk = wkbks.Open(fileName); ... } catch (Exception ex) { } if (wkbk != null) { excelApp.DisplayAlerts = false; wkbk.Close(false); Marshal.FinalReleaseComObject(wkbk); wkbk = null; } if (wkbks != null) { wkbks.Close(); Marshal.FinalReleaseComObject(wkbks); wkbks = null; } if (excelApp != null) { // Close Excel. excelApp.Quit(); Marshal.FinalReleaseComObject(excelApp); excelApp = null; } // Change culture back from en-us to the original culture. thisThread.CurrentCulture = originalCulture; } 
+1
source share

I finally closed it. You need to add a variable for the Workbooks collection, and then use FinalReleaseComObject, as indicated in other answers. I assume that every possible Excel COM object that you use should be deleted this way.

 try { // Create an instance of Microsoft Excel and make it invisible excelApp = new Excel.Application(); excelApp.DisplayAlerts = false; excelApp.Visible = false; // open a Workbook and get the active Worksheet excelWorkbooks = excelApp.Workbooks; excelWorkbook = excelWorkbooks.Open(excelFile, Type.Missing, true); excelWorkSheet1 = excelWorkbook.ActiveSheet; } catch { throw; } finally { NAR( excelWorkSheet1 ); excelWorkbook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value); NAR(excelWorkbook); NAR(excelWorkbooks); excelApp.Quit(); NAR(excelApp); } } private void NAR(object o) { try { System.Runtime.InteropServices.Marshal.FinalReleaseComObject( o ); } catch { } finally { o = null; } } 
0
source share

All Articles