-1

I have to open an excel file and want to get the data to word a document. I use to this code:

private Excel.Application excelapp;
Type ExcelType = Type.GetTypeFromProgID("Excel.Application");
dynamic ExcelInst = Activator.CreateInstance(ExcelType);
this.excelapp = ExcelInst;

this.workbook = this.excelapp.Workbooks.Open(Filename : this.filePath, ReadOnly: true);

I used all the techniques to close/quit/dispose the opened process (except for Process.Kill), but those won't work. How do I fully terminate any running background tasks?

  • Show what you've tried that didn't work. People really do ***not*** want to make suggestions only to be told "I already tried that and it didn't work.", so it's necessary to list those things in the question - you can use the [edit] link to do so. Is there any reason you're not using `this.excelapp = new Excel.Application();`? And why is this tagged with ms-word when the question is not about Word? – Cindy Meister Jan 07 '20 at 11:43
  • 2
    https://stackoverflow.com/a/25135685/17034 – Hans Passant Jan 07 '20 at 12:39

4 Answers4

1

My understanding is that since interop uses “COM” objects, you need to “release" those objects. Something like…

Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(xlApp);

in that order. This should release those objects from the background tasks

I have had success with the following approach when using office-interop… Set up all the Excel/Word/Outlook. Etc.… interop stuff in a try/catch/finally statement. This should almost guarantee that your code will properly close and “release” the resources it uses even if there is an exception. Otherwise, the code will always be susceptible to leaking a resource.

Word.Application app = null;
Word.Document doc = null;
try {
  app = new Word.Application();
  //app.Visible = true;
  doc = app.Documents.Add();
  // do some stuff with the document…
  doc.SaveAs2(filename);
  MessageBox.Show("Document created successfully !");
}
catch (Exception e) {
  MessageBox.Show("ERROR: " + e.Message);
}
finally {
  if (doc != null) {
    doc.Close();
    Marshal.ReleaseComObject(doc);
  }
  if (app != null) {
    app.Quit();
    Marshal.ReleaseComObject(app);
  }
}
JohnG
  • 9,259
  • 2
  • 20
  • 29
0

You just need to call the Quit method of the Excel Application class when you are done:

private Excel.Application excelapp;
Type ExcelType = Type.GetTypeFromProgID("Excel.Application");
dynamic ExcelInst = Activator.CreateInstance(ExcelType);
this.excelapp = ExcelInst;

this.workbook = this.excelapp.Workbooks.Open(Filename : this.filePath, ReadOnly: true);

' do whatever you need there

this.workbook.Save();

this.excelapp.Quit();

If unsaved workbooks are open when you use this method, Excel displays a dialog box asking whether you want to save the changes. You can prevent this by saving all workbooks before using the Quit method or by setting the DisplayAlerts property to False. When this property is False, Excel doesn't display the dialog box when you quit with unsaved workbooks; it quits without saving them.

If you set the Saved property for a workbook to True without saving the workbook to the disk, Excel will quit without asking you to save the workbook. Note: this does not save the workbook; it just makes it look like it's saved.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
-1

I use the following to open excel and read / update it.

Excel.Application app;
Excel.Workbook wb;
private void openAndRead()
{

 app = new Excel.Application();
 wb = app.Workbooks.Open(YourFileHere);

//do stuff here read or write
//app.ActiveSheet.Cells[1, "A"] = "write this in cell A1";
//string read= app.ActiveSheet.Cells[1, "A"]; 

}

private void closeExcel ()
{
 app.DisplayAlerts = false; //this will stop popup questions from excel
 wb.Close();
 app.Quit();
}
Joeri E
  • 111
  • 9
  • in your code you have the control over "app" you can keep track of it and use it wherever you see fit. if you then want to close the app you dont need to search for it in the process since you have full control. – Joeri E Jan 07 '20 at 08:42
  • But how is it different from what the OP has? – GSerg Jan 07 '20 at 13:33
  • OP does not keep track of his open app and never closes/quits it – Joeri E Jan 08 '20 at 08:43
-1

If you want to be confident that EXCEL.EXE process will go away, there's one way to realize it. May be this is not the elegant solution, but at least it does work. The main idea is to catch the Excel window's handle. Having this handle, you can get its process and shut it down.

WARNING: If you don't make Excel window visible, this method WILL NOT work!

using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;

void Kill_Excel()
{
    // Create instance of Excel application.
    // If you don't make Excel window visible, this method WILL NOT work!
    Excel.Application excel = new Excel.Application { Visible = true };
            
    // Catch Excel window handle
    IntPtr hwnd = new IntPtr(excel.Hwnd);
    // Get EXCEL.EXE process
    Process xlproc = Process.GetProcesses().Where(p => p.MainWindowHandle == hwnd).First();

    // Do some operations
    Excel.Workbook book = excel.Workbooks.Add();
    Excel.Worksheet sheet = book.Sheets[1] as Excel.Worksheet;
    sheet.Cells[1, 1] = "Hello!";

    // Close Excel
    book.Close(SaveChanges: false);
    excel.Quit();

    // Garbage collection
    GC.Collect();
    GC.WaitForFullGCComplete();

    // Kill process - FOR SURE! :)
    xlproc.Kill();
}
Community
  • 1
  • 1
JohnyL
  • 6,894
  • 3
  • 22
  • 41