-1

I have a C# application that creates an excel file. But if the file is left open and the app is run the second time, it throws IO exception (since, in the code I am replacing the existing file with new one) Now, I want to check if the file is open and kill the excel.exe process that is referencing this file. Is there any way this can be achieved?

Note: There might be several excel files open. I want to close only the process that is using my file.

xlFilePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
File.Copy(xlFilePath + "\\file.xlsx", String.Format("{0}\\OutputFile{1}.{2}.xlsx", xlFilePath, DateTime.Now.Year, DateTime.Now.Month), true);
xlFilePath = Path.Combine(xlFilePath, String.Format("{0}\\OutputFile{1}.{2}.xlsx", xlFilePath, DateTime.Now.Year, DateTime.Now.Month));

appl = new Excel.Application(Visible = false);
wbookss = appl.Workbooks;
wbook = wbookss.Open(xlFilePath);
//Excel.Worksheets wsheetss = appl.Worksheets;
wsheet = wbook.Sheets["Sheet1"];

Application_GenerateReport(wsheet);
Clipboard.Clear();
wbook.Close(true);
wbookss.Close();
appl.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(wsheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbookss);
System.Runtime.InteropServices.Marshal.ReleaseComObject(appl);

EDIT: The file remains open if there was an exception in the last run. If it is opened by a user, it can be killed by checking the MainWindowTitle property (As suggested by Yeldar).

SharpCoder
  • 49
  • 2
  • 8
  • I would say, that I think you are approaching the problem from the wrong end. Your program should gracefully handle this exception. Perhaps with a possible retry? That's much nicer than attempting to send Excel to oblivion (taking any potential user changes with it). Plus Office tends to nag you with _"a problem occurred opening this file before, open it again?"_ or some such –  Nov 27 '15 at 05:57
  • ^The report is generated only using this app, never modified manually. – SharpCoder Nov 27 '15 at 06:01
  • [This post](http://stackoverflow.com/questions/13807102/find-all-open-excel-workbooks) describes how you can get that running excel instance. You should consider that instance instead of killing it – Oguz Ozgul Nov 27 '15 at 06:06

2 Answers2

1

Another solution could be:

System.Diagnostics.Process.Start("CMD.exe","taskkill /f /im excel.exe");

This line will call command prompt and running the command taskkill.

All opening excel programs will be killed in this way.

Updated: (For one file)

System.Diagnostics.Process.Start("CMD.exe","taskkill /FI "WindowTitle eq Microsoft Excel - filename.xls");
Tony Wu
  • 1,040
  • 18
  • 28
0

As Excel stores the name of the opened file in its title like this:

Microsoft Excel - filename.xls

You can iterate through the processes and kill the one with the given name:

string filename = "mylist.xls";
var excelProcesses = Process.GetProcessesByName("excel");

foreach (var process in excelProcesses)
{
  if (process.MainWindowTitle == $"Microsoft Excel - {filename}") // String.Format for pre-C# 6.0 
  {
     process.Kill();
  }
}

Note that:

  • it will also close all opened files with the same name
  • it will abandon any changes that user could change
  • title of Excel window may (or not, not sure, need to check) vary from version to version

However, as I said in comments, it is better to fix causes, but not consequences - just make your program start new Excel application without errors.

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101