数据访问后在C#中closuresExcel应用程序过程

我正在用C#编写一个应用程序,打开一个用于读/写操作的Excel模板文件。 我想在用户closures应用程序时,excel应用程序进程已经closures,而不保存excel文件。 多次运行应用程序后,查看我的任务pipe理器。

在这里输入图像说明

我用这个代码打开excel文件:

public Excel.Application excelApp = new Excel.Application(); public Excel.Workbook excelBook; excelBook = excelApp.Workbooks.Add(@"C:/pape.xltx"); 

和数据访问我使用这个代码:

 Excel.Worksheet excelSheet = (Worksheet)(excelBook.Worksheets[1]); excelSheet.DisplayRightToLeft = true; Range rng; rng = excelSheet.get_Range("C2"); rng.Value2 = txtName.Text; 

我看到类似的问题在这个问题和这个 stackoverflow和testing答案,但它不起作用。

尝试这个:

 excelBook.Close(0); excelApp.Quit(); 

closures工作簿时,您有三个可选参数:

 Workbook.close SaveChanges, filename, routeworkbook 

Workbook.Close(false)或者如果您正在执行后期绑定,它有时更容易使用zero Workbook.Close(0)这是我自动closures工作簿时所做的工作。

另外我去了,查找它的文档,并在这里find它: Excel工作簿closures

谢谢,

 xlBook.Save(); xlBook.Close(true); xlApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 

试试这个..它为我工作…你应该释放这个xl应用程序对象来停止进程。

想想这个,它杀死了这个过程:

 System.Diagnostics.Process[] process=System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (!string.IsNullOrEmpty(p.ProcessName)) { try { p.Kill(); } catch { } } } 

另外,你是否正常closures它?

 myWorkbook.SaveAs(@"C:/pape.xltx", missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing); excelBook.Close(null, null, null); // close your workbook excelApp.Quit(); // exit excel application excel = null; // set to NULL 

参考: https : //stackoverflow.com/a/17367570/132599

避免使用双点呼叫expression式,例如:

 var workbook = excel.Workbooks.Open(/*params*/) 

…因为通过这种方式,不仅可以为工作簿创buildRCW对象,还可以为工作簿创buildRCW对象,并且也应该释放它(如果不维护对象的引用,则不可能)。

这为我解决了这个问题。 你的代码变成:

 public Excel.Application excelApp = new Excel.Application(); public Excel.Workbooks workbooks; public Excel.Workbook excelBook; workbooks = excelApp.Workbooks; excelBook = workbooks.Add(@"C:/pape.xltx"); ... Excel.Sheets sheets = excelBook.Worksheets; Excel.Worksheet excelSheet = (Worksheet)(sheets[1]); excelSheet.DisplayRightToLeft = true; Range rng; rng = excelSheet.get_Range("C2"); rng.Value2 = txtName.Text; 

然后释放所有这些对象:

 System.Runtime.InteropServices.Marshal.ReleaseComObject(rng); System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets); excelBook .Save(); excelBook .Close(true); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); excelApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 

try {} finally {}封装在一个try {} finally {}以确保即使出现错误(即可能出错的地方),所有东西都会被释放。

 public Excel.Application excelApp = null; public Excel.Workbooks workbooks = null; ... try { excelApp = new Excel.Application(); workbooks = excelApp.Workbooks; ... } finally { ... if (workbooks != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); excelApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); } 

杀死Excel并不总是很容易; 看到这篇文章: 50种方法来杀死Excel

本文从微软(微软知识库文章)的最佳build议如何让Excel很好地退出,但如果有必要,也可以通过杀死进程来确保它。 我喜欢有第二个降落伞。

确保closures所有打开的工作簿,退出应用程序并释放xlApp对象。 最后检查过程是否还活着,如果是的话就杀了它。

本文还确保我们不杀死所有的Excel进程,但只杀死已启动的确切进程。

请参阅从窗口句柄获取进程

这里是我使用的代码:(每次工作)

 Sub UsingExcel() 'declare process; will be used later to attach the Excel process Dim XLProc As Process 'call the sub that will do some work with Excel 'calling Excel in a separate routine will ensure that it is 'out of scope when calling GC.Collect 'this works better especially in debug mode DoOfficeWork(XLProc) 'Do garbage collection to release the COM pointers 'http://support.microsoft.com/kb/317109 GC.Collect() GC.WaitForPendingFinalizers() 'I prefer to have two parachutes when dealing with the Excel process 'this is the last answer if garbage collection were to fail If Not XLProc Is Nothing AndAlso Not XLProc.HasExited Then XLProc.Kill() End If End Sub 'http://msdn.microsoft.com/en-us/library/ms633522%28v=vs.85%29.aspx <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _ Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _ ByRef lpdwProcessId As Integer) As Integer End Function Private Sub ExcelWork(ByRef XLProc As Process) 'start the application using late binding Dim xlApp As Object = CreateObject("Excel.Application") 'or use early binding 'Dim xlApp As Microsoft.Office.Interop.Excel 'get the window handle Dim xlHWND As Integer = xlApp.hwnd 'this will have the process ID after call to GetWindowThreadProcessId Dim ProcIdXL As Integer = 0 'get the process ID GetWindowThreadProcessId(xlHWND, ProcIdXL) 'get the process XLProc = Process.GetProcessById(ProcIdXL) 'do some work with Excel here using xlApp 'be sure to save and close all workbooks when done 'release all objects used (except xlApp) using NAR(x) 'Quit Excel xlApp.quit() 'Release NAR(xlApp) End Sub Private Sub NAR(ByVal o As Object) 'http://support.microsoft.com/kb/317109 Try While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) End While Catch Finally o = Nothing End Try End Sub 

excelBook.Close(); excelApp.Quit(); 添加代码的结尾,可能就够了。 它正在处理我的代码

我遇到了同样的问题,并尝试了很多方法来解决它,但不工作。 最后,我find了我的方式。 有些参考资料在此input链接描述

希望我的代码可以帮助未来的人。 我已经花了两天多的时间来解决这个问题。 以下是我的代码:

 //get current in useing excel Process[] excelProcsOld = Process.GetProcessesByName("EXCEL"); Excel.Application myExcelApp = null; Excel.Workbooks excelWorkbookTemplate = null; Excel.Workbook excelWorkbook = null; try{ //DO sth using myExcelApp , excelWorkbookTemplate, excelWorkbook } catch (Exception ex ){ } finally { //Compare the EXCEL ID and Kill it Process[] excelProcsNew = Process.GetProcessesByName("EXCEL"); foreach (Process procNew in excelProcsNew) { int exist = 0; foreach (Process procOld in excelProcsOld) { if (procNew.Id == procOld.Id) { exist++; } } if (exist == 0) { procNew.Kill(); } } } 
  wb.Close(); app.Quit(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (!string.IsNullOrEmpty(p.ProcessName) && p.StartTime.AddSeconds(+10) > DateTime.Now) { try { p.Kill(); } catch { } } } 

它closures最后10秒的过程,名称为“Excel”

closures所有excel过程的正确方法

 var _excel = new Application(); foreach (Workbook _workbook in _excel.Workbooks) { _workbook.Close(0); } _excel.Quit(); _excel = null; var process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (var p in process) { if (!string.IsNullOrEmpty(p.ProcessName)) { try { p.Kill(); } catch { } } } 

基于另一种解决scheme。 我使用这个:

 IntPtr xAsIntPtr = new IntPtr(excelObj.Application.Hwnd); excelObj.ActiveWorkbook.Close(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (p.MainWindowHandle == xAsIntPtr) { try { p.Kill(); } catch { } } } 

使用“MainWindowHandle”来识别过程并closures他。

excelObj:这是我的Application Interop excel对象

  GetWindowThreadProcessId((IntPtr)app.Hwnd, out iProcessId); wb.Close(true,Missing.Value,Missing.Value); app.Quit(); System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("Excel"); foreach (System.Diagnostics.Process p in process) { if (p.Id == iProcessId) { try { p.Kill(); } catch { } } } } [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); uint iProcessId = 0; 

这GetWindowThreadProcessIdfind正确的进程IDØexcell ….杀死它后….享受它!