Excel process not closing
我有一个不会关闭Excel进程的C程序。基本上,它会找到一个字符串出现在Excel范围内的实例数。我试过各种方法,但都不管用。有一个窗体正在调用此方法,但这不应改变进程未关闭的原因。我看过汉斯·帕桑特的建议,但都没用。
编辑:我试过上面提到的东西,但还是不能关闭。这是我的更新代码。edit:尝试了整个过程。kill()并且它可以工作,但是对于一些应该工作的东西来说,它看起来有点像是一个黑客。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 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抱歉)。基本上,它向你展示了如何正确地设置和拆卸Office应用程序,这样当你完成它时,它就会关闭。
魔法发生的地方是
编辑:您需要为您创建的每个Excel对象调用finalReleaseComObject。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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)创建Excel变量时,将所有值设置为空(这样可以避免未启动的错误)。
2)在不首先释放变量的情况下,不要重复使用变量。
3)不要用双点号
4)释放所有Excel变量。越快越好。
5)设置为空。
将文化设置为"en-us"。有一个bug使Excel在某些文化中崩溃。这确保了它不会。
下面是您的代码应该如何构造的一个概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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; } |
我终于把它关闭了。您需要为工作簿集合添加一个变量,然后使用finalReleaseComObject,如其他答案中所述。我想您使用的所有可能的Excel COM对象都必须这样处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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; } } |