取出数据后closuresEXCEL应用程序进程

我想通过这种方式获取列表中的Excel文件的列数据:

private void Form1_Load(object sender, EventArgs e) { Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"D:/test.xlsx"); Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1]; Excel.Range xlRange = xlWorksheet.UsedRange; int rowCount = xlRange.Rows.Count; int colCount = xlRange.Columns.Count; List<string> FirstColumnValues = new List<string>(); List<string> SecondColumnValues = new List<string>(); for (int row=1; row <= rowCount; row++) { for (int col = 1; col <= colCount; col++) { switch (col) { case 1: FirstColumnValues.Add(xlRange.Cells[row, col].Value2.ToString()); break; case 2: SecondColumnValues.Add(xlRange.Cells[row, col].Value2.ToString()); break; } } } if (FirstColumnValues.Count != 0 && SecondColumnValues.Count != 0) { xlWorkbook.Close(); xlApp.Quit(); MessageBox.Show("Completed"); Marshal.ReleaseComObject(xlRange); Marshal.ReleaseComObject(xlWorksheet); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlApp); xlApp = null; } } 

问题是,过程EXCEL.EXE不closures,即使我已经尝试所有的事情来正确closures它。 我知道这里有很多关于如何正确closuresexcel进程的问题。 但我不是一个专业人员,我已经尝试了几乎所有我能做的事情。 仍然没有运气。

那么,有人可以告诉我这个代码有什么问题吗? 当所有数据都存储在列表中时,如何closures这个过程?

我以前去过那里。 这里有一篇文章真的帮我解决了这个问题:

http://devcity.net/Articles/239/1/article.aspx

Excel似乎对结束这个过程非常固执。 你将更有可能最终杀死使用System.Diagnostics.Process进程。

我知道这个问题已经被回答了,但是我想我会分享一下我发现要解决同样的问题。 希望有人会觉得这有用。 这是在vb.net,但我相信它可以被翻译。

 Dim proc As System.Diagnostics.Process For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL") If proc.MainWindowTitle.ToString = "" Then proc.Kill() End If Next 

我发现,当我通过我的应用程序打开Excel文件时,窗口标题为空,所以不是closures每个正在运行的Excel进程,而是closures没有标题的Excel进程。

编辑:

如果你打算终止这个过程,因为你不能find剩余的variables (基本上你用两个点设置的variables),那么至less杀掉正确的Excel实例:

 [DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId); ... if (xlApp != null) { GetWindowThreadProcessId(new IntPtr(xlApp.Hwnd), ref excelProcessId); Process ExcelProc = Process.GetProcessById(excelProcessId); if (ExcelProc != null) { ExcelProc.Kill(); } 

我不主张杀死进程,你应该用VSTO Contrib正确清理,例如:

 using (var xlApp = new Microsoft.Office.Interop.Excel.Application().WithComCleanup()) 

也许,你可能会考虑使用try{}catch{}finally{} ,然后尝试Marshal.FinalReleaseComObject 。

不知道你是否看过这个post ,也可能给你一些见解。

确保运行的Excel实例最终终止的最简单的方法(即当您的应用程序退出时)是将try / finally块中的顶层对象封装起来。

 Excel.Application xlApp; try{ xlApp = new Excel.Application(); ...do some work... } finally{ xlApp.DisableAlerts=True; xlApp.Quit(); xlApp.DisableAlerts=False; Marshal.ReleaseComObject(xlApp); } //If you don't mind having the Excel process kept alive for a while, //you don't even have to call ReleaseComObject() on the intermediate objects. //The runtime will eventually free the underlying COM objects. //If you want to clean up right away, your bookkeeping needs to be more thorough. //Every time you access a method or property that returns a runtime callable wrapper //(System.__ComObject), you'll need to assign them to a variable //and make sure Marshal.ReleaseComObject() is called. // More thorough bookkeeping... Excel.Application xlApp; try{ xlApp = new Excel.Application(); Excel.Workbooks xlWorkbooks = xlApp.Workbooks; Excel.Workbook xlWorkbook = xlWorkbooks.Open(@"D:/test.xlsx"); Excel.Sheets xlSheets = xlWorkbook.Sheets; Excel.Worksheet xlWorksheet = xlSheets[1]; Excel.Range xlRange = xlWorksheet.UsedRange; ...inside the loop... Excel.Range xlCell = xlRange.Cells[row, col]; FirstColumnValues.Add(xlCell.Value2.ToString()); Marshal.ReleaseComObject(xlCell); ...inside the loop... Excel.Range xlCell = xlRange.Cells[row, col]; SecondColumnValues.Add(xlCell.Value2.ToString()); Marshal.ReleaseComObject(xlCell); ...do more work... ...clean up... Marshal.ReleaseComObject(xlRange); Marshal.ReleaseComObject(xlWorksheet); Marshal.ReleaseComObject(xlSheets); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlWorkbooks); } finally{ xlApp.DisableAlerts=True; xlApp.Quit(); xlApp.DisableAlerts=False; Marshal.ReleaseComObject(xlApp); }