Closing an Excel application process in C # after accessing data

I am writing a C # application that opens an Excel template file for read / write operations. I want the user to close the application, the exclusive application process was closed without saving the excel file. See My task manager after several application launches.

enter image description here

I use this code to open an excel file:

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

and to access the data I use this code:

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

I see similar questions in stackoverflow, such as this question and this one , and test the answers, but this does not work.

+52
c # excel kill-process visual-studio-2012 excel-interop
Jul 21 '13 at 22:20
source share
11 answers

Try the following:

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

When you close the workbook, you have three optional parameters:

 Workbook.close SaveChanges, filename, routeworkbook 

Workbook.Close(false) or if you are doing late binding, it is sometimes easier to use null Workbook.Close(0) This is how I did it when automating closing books.

And I went and looked at the documentation for it, and found it here: Close the Excel workbook

Thank,

+62
Jul 21 '13 at 23:03
source share
— -
 xlBook.Save(); xlBook.Close(true); xlApp.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 

try this .. it worked for me ... you have to free this xl application object to stop the process.

+17
Nov 26 '13 at 9:23
source share

Think about it, it kills the process:

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

Also, were you trying to just close it normally?

 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 
+9
Jul 21 '13 at 22:27
source share

Link: stack overflow

Avoid using expressions with two dots, such as:

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

... because in this way you create RCW objects not only for the workbook, but also for workbooks, and you must also release it (which is impossible if the reference to the object is not supported).

This solved the problem for me. Your code will look like this:

 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; 

And then release all of these objects:

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

I wrap this in try {} finally {} to ensure that everything will be released even if something goes wrong (what could go wrong?), For example.

 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); } 
+6
Jan 22 '15 at 2:24
source share

Killing Excel is not always easy; see this article: 50 Ways to Kill Excel

This article contains the best advice from Microsoft ( MS Knowlege Base Article ) on how to get Excel to stop working, but then also makes sure of it, killing the process if necessary. I like to have a second parachute.

Be sure to close all open books, close the application, and release the xlApp object. Finally, check if the process is alive, and if so, kill it.

This article also ensures that we do not kill all Excel processes, but only kill the exact process that was started.

See also Get process from control window.

Here is the code I use: (works every time)

 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 
+2
Jul 23 '13 at 3:53 on
source share

excelBook.Close (); excelApp.Quit (); add the end of the code, this may be enough. he is working on my code

+1
Jul 21 '13 at 22:37
source share

I met the same problems and tried many methods to solve it, but it does not work. Finally, I found it in my opinion. Some link enter the link here

Hope my code helps someone in the future. It took me more than two days to solve this problem. Below is my code:

 //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(); } } } 
+1
Mar 16 '17 at 9:42 on
source share
  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 { } } } 

It closes the last 10 second process called "Excel"

0
May 27 '15 at 8:05
source share

The right way to close the whole excel process

 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 { } } } 
0
May 17 '16 at 10:47
source share

Based on other solutions. I use this:

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

Using "MainWindowHandle" to identify the process and close it.

excelObj: This is my Interop excel objecto application

0
May 16 '17 at 10:51 p.m.
source share
  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; 

this GetWindowThreadProcessId finds the correct process identifier o excell .... After killing ... Enjoy it !!!

-one
Jun 16 '15 at 13:37
source share



All Articles