Close Excel Workbook

I have some code that opens an xls workbook;

Excel.Workbooks workBooks; workBooks = excelApp.Workbooks; workbook = workBooks.Open(sourceFilePath + sourceFileName + ".xls"); 

Then I will get a worksheet;

 worksheets = workbook.Worksheets; worksheet = worksheets.get_Item("Standard"); 

Then I save the file as csv;

 worksheet.SaveAs(sourceFilePath + sourceFileName + ".csv", Excel.XlFileFormat.xlCSVWindows, Type.Missing, Type.Missing, false, false, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing); 

Then I try to close the book;

 Marshal.FinalReleaseComObject(worksheet); Marshal.FinalReleaseComObject(worksheets); workbook.Close(); Marshal.FinalReleaseComObject(workbook); 

However, every time I get to the line workbook.Close (), the system stops.

If I do not SaveAs, then the workbook just closes.

How to close a book?

change

The Task Manager shows that Excel.exe is still running. Closing will result in an error in my code.

change 2

I already saw the link referenced by SO, and it did not solve the problem.

+4
source share
5 answers

Here is the solution

first: using EXCEL = Microsoft.Office.Interop.Excel;

and then path is where your excel is.

  EXCEL.Application excel = new EXCEL.Application(); try { EXCEL.Workbook book = excel.Application.Workbooks.Open(path); EXCEL.Worksheet sheet = book.Worksheets[1]; // yout operation } catch (Exception ex) { MessageBox.Show("readExcel:" + ex.Message); } finally { KillExcel(excel); System.Threading.Thread.Sleep(100); } [DllImport("User32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId); private static void KillExcel(EXCEL.Application theApp) { int id = 0; IntPtr intptr = new IntPtr(theApp.Hwnd); System.Diagnostics.Process p = null; try { GetWindowThreadProcessId(intptr, out id); p = System.Diagnostics.Process.GetProcessById(id); if (p != null) { p.Kill(); p.Dispose(); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("KillExcel:" + ex.Message); } } 
+8
source

Why not merge 2. This will take care of any closing issues before the save is complete. The Close file has an option to save the file.

 workbook.Close(true, fileName, Missing.Value); 

Also, if the file is saved correctly, and your problem is solely due to the fact that the excel.exe process is still running, this may be due to the fact that you did not close and did not release EVERYTHING. I had this before and developed a more complete closure procedure. My code to disable excel file:

  book.Close(true, fileName, Missing.Value); //close and save individual book allBooks.Close(); //close all books excel.Quit(); Marshal.ReleaseComObject(allCells); //any used range objects Marshal.ReleaseComObject(sheet); Marshal.ReleaseComObject(sheets); Marshal.ReleaseComObject(book); Marshal.ReleaseComObject(allBooks); Marshal.ReleaseComObject(excel); 

This works 100% for me.

+5
source

Have you considered the fact that the system can still save the file when you try to close it? I'm just saying, of course, to add a delay (Thread.Sleep (1000) in C #, for example) before closing, to see if this is a problem.

0
source

This question continues to appear:

How to properly clean Excel interaction objects in C #

You need to call System.Runtime.InteropServices.Marshal.ReleaseComObject () for every excel object you use, even invisible ones, for example:

var worksheet = excelApp.Worksheets.Open()

There are two objects here: 1. The obvious "Worksheet" is opened using Open () 2. The "Invisible" collection is "Worksheets".

Both of them should be released (so that you better keep the link to worksheets):

  var wkCol = excelApp.Worksheets;
 var worksheet = wkCol.Open ();
0
source
  EXCEL.Application excel = new EXCEL.Application(); try { EXCEL.Workbook book = excel.Application.Workbooks.Open(path); EXCEL.Worksheet sheet = book.Worksheets[1]; // yout operation } catch (Exception ex) { MessageBox.Show("readExcel:" + ex.Message); } finally { KillExcel(excel); System.Threading.Thread.Sleep(100); } [DllImport("User32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId); private static void KillExcel(EXCEL.Application theApp) { int id = 0; IntPtr intptr = new IntPtr(theApp.Hwnd); System.Diagnostics.Process p = null; try { GetWindowThreadProcessId(intptr, out id); p = System.Diagnostics.Process.GetProcessById(id); if (p != null) { p.Kill(); p.Dispose(); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("KillExcel:" + ex.Message); } } 

thanks !!!!

0
source

Source: https://habr.com/ru/post/1489403/


All Articles