Excel进程不closures

我有这个C#程序,从不closuresExcel进程。 基本上它发现一个string出现在Excel范围内的实例的数目。 我已经尝试了各种各样的东西,但是不起作用。 有一个窗体调用这个方法,但是这不应该改变为什么这个过程不closures。 我看了Hans Passant的build议,但都没有工作。

编辑:我试过提到的事情,它仍然不会closures。 这是我更新的代码。 编辑:试了整个Process.Kill(),它的工作原理,但它似乎有点应该只是工作的黑客。

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(); } */ } } } 

在.NET应用程序断开连接之后,Office应用程序保持打开状态,这是一个有趣的知识库。

从Visual Studio .NET客户端自动化后,Office应用程序不会退出

代码示例都在链接(vb.net抱歉)。 基本上,它告诉你如何正确设置和拆除办公室的应用程序,以便它完成后closures。

System.Runtime.InteropServices.Marshal.FinalReleaseComObject是魔术发生的地方。

编辑:您需要为您创build的每个Excel对象调用FinalReleaseComObject。

 if (excelWorkSheet1 != null) { Marshal.FinalReleaseComObject(excelWorkSheet1); excelWorkSheet1 = null; } if (excelWorkbook != null) { Marshal.FinalReleaseComObject(excelWorkbook); excelWorkbook = null; } if (excelApp != null) { Marshal.FinalReleaseComObject(excelApp); excelApp = null; } 

DotNet只有在释放所有的句柄后才释放COM对象。 我所做的是评论一切,然后加回一部分。 看看它是否释放Excel。 如果它不遵循以下规则。 当它释放时,添加更多的代码,直到它不再释放。

1)创buildExcelvariables时,将所有值设置为空(这样可以避免不发生错误)

2)不要重复使用variables,而不要先释放variablesMarshal.FinalReleaseComObject

3)不要双点(ab = z) 。 dotNet创build一个临时variables,它不会被释放。

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

4)发布所有的Excelvariables。 越快越好。

5)将其设置回NULL。

将文化设置为“en-US”。 有一个错误,Excel与一些文化崩溃。 这确保不会。

下面是如何构build你的代码的一个想法:

  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; } 

我终于把它closures了。 您需要为Workbooks集合添加一个variables,然后按照其他答案中所述使用FinalReleaseComObject。 我猜想你使用的每个可能的Excel COM对象都必须这样处理。

 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; } }