С# = Почему процессы Excel не заканчиваются?
У меня есть следующий код:
private bool IsMousetrapFile(string path)
{
logger.Log(validateFileMessage + path);
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbooks workbooks = xlApp.Workbooks;
Excel.Workbook xlWorkBook = workbooks.Open(path, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Excel.Sheets worksheets = (Excel.Sheets)xlWorkBook.Worksheets;
Excel.Worksheet ws = null;
foreach (string sheet in expectedWorksheets)
{
try
{
ws = (Excel.Worksheet)worksheets.get_Item(sheet);
logger.Log(validMousetrapFileMessage + path);
}
catch
{
logger.Log(validateSheetError + sheet + ": " + path);
if (ws != null)
Marshal.ReleaseComObject(ws);
Marshal.ReleaseComObject(worksheets);
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(xlApp);
return false;
}
}
if (ws != null)
Marshal.ReleaseComObject(ws);
Marshal.ReleaseComObject(worksheets);
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(xlApp);
return true;
}
Фактически, он проверяет, содержит ли книга Excel специальные листы. Независимо от того, есть или нет, я хочу, чтобы процессы Excel заканчивались. Однако при каждом открытии новой книги новый процесс добавляется и никогда не удаляется?
PS. Я знаю, что там есть дублированный код... он должен быть убран в ближайшее время:)
Ответы
Ответ 1
Используйте Excel.Application.Quit()
, когда закончите с обработкой или тем, что вы делаете.
В вашем случае: xlApp.Quit();
UPDATE:
@Lasse V. Karlsen указал, что делать, если Excel уже работает. Ну, вот одно решение: (я не тестировал код, это просто для того, чтобы дать вам представление)
private void TestMethod()
{
bool excelWasRunning = System.Diagnostics.Process.GetProcessesByName("excel").Length > 0;
// your code
if (!excelWasRunning)
{
xlApp.Quit();
}
}
Ответ 2
Мое решение
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
private void GenerateExcel()
{
var excel = new Microsoft.Office.Interop.Excel.Application();
int id;
// Find the Process Id
GetWindowThreadProcessId(excel.Hwnd, out id);
Process excelProcess = Process.GetProcessById(id);
try
{
// Your code
}
finally
{
excel.Quit();
// Kill him !
excelProcess.Kill();
}
Ответ 3
Несколько дней назад я реализовал Export/Import.
Я получил код ниже, когда я искал в Google, и все работает отлично.
ExportToExcel()
{
try
{
//your code
}
catch (Exception ex)
{
}
finally
{
TryQuitExcel(Application_object);
}
}
private static void TryQuitExcel(Microsoft.Office.Interop.Excel.Application application)
{
try
{
if (application != null &&
application.Workbooks != null &&
application.Workbooks.Count < 2)
{
application.DisplayAlerts = false;
application.Quit();
Kill(application.Hwnd);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(application);
application = null;
}
}
catch
{
/// Excel may have been closed via Windows Task Manager.
/// Skip the close.
}
}
private static void Kill(int hwnd)
{
int excelPID = 0;
int handle = hwnd;
GetWindowThreadProcessId(handle, ref excelPID);
Process process = null;
try
{
process = Process.GetProcessById(excelPID);
//
// If we found a matching Excel proceess with no main window
// associated main window, kill it.
//
if (process != null)
{
if (process.ProcessName.ToUpper() == "EXCEL" && !process.HasExited)
process.Kill();
}
}
catch { }
}