Убийство процесса взаимодействия - PullRequest
4 голосов
/ 26 ноября 2008

У меня в программе есть следующее (написано на VB.NET):

Imports Microsoft.Office.Interop.Excel

Public Class Form1
    Dim eApp As New Excel.Application
    Dim w As Excel.Workbook
    w = eApp.Workbooks.Open( "path.xls", ReadOnly:=True)
    .. Processing Code ..
    //Attempts at killing the excel application
    w.Close()
    eApp.Workbooks.Close()
    eApp.Quit()
End Class

Когда я запускаю это пару раз, в диспетчере задач появляется куча экземпляров EXCEL.EXE. Как я могу убить эти процессы в коде? Все в коде были опробованы и не работали.

Ответы [ 9 ]

3 голосов
/ 26 ноября 2008

Я должен был сделать это некоторое время назад в NET 1.1, поэтому, пожалуйста, прости ржавчину.

На eApp был Hwind (дескриптор окна win32 - http://msdn.microsoft.com/en-us/library/bb255823.aspx) или подобный объект. Мне пришлось использовать это и pInvoke (http://www.pinvoke.net/default.aspx/user32.GetWindowThreadProcessId), чтобы получить идентификатор процесса. С этим я смог сделать Process.Kill () на exe.

Возможно, есть лучший способ сделать это сейчас, но это должно сработать.

3 голосов
/ 26 ноября 2008

зацикливать строку кода ниже, пока результат не станет равным нулю или меньше

System.Runtime.InteropServices.Marshal.ReleaseComObject(eApp)

или проверьте эту ссылку

2 голосов
/ 27 ноября 2008

Чтобы выйти из Excel, вам нужно вызвать Application.Quit и использовать один из следующих методов.

  • Вызовите Marshal.ReleaseComObject для каждого объекта Excel, который вы создаете. Есть статья базы знаний , в которой описывается, как это сделать. Например, в вашем примере кода «eApp.Workbooks.Open» создается экземпляр объекта Workbooks без присвоения ему переменной. Вам необходимо назначить переменную, как описано в статье базы знаний, чтобы впоследствии ее можно было освободить. Суть в том, что при любых простейших сценариях автоматизации очень трудно быть уверенным, что вы всегда освобождаете все такие объекты во всех путях кода (например, с помощью try / finally, чтобы убедиться, что они освобождаются при возникновении исключения).

  • Вызовите GC.Collect и GC.WaitForPendingFinalizers после освобождения последнего объекта Excel. Некоторые люди считают, что вам, возможно, придется сделать это дважды.

1 голос
/ 23 ноября 2012

Запустите Excel:

Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = xlApp.Workbooks.Open(...);
Worksheet ws = (Worksheet)wb.Worksheets[1];

Убить Excel:

System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
wb = null;
ws = null;

uint idProcess;
GetWindowThreadProcessId((IntPtr)xlApp.Hwnd, out idProcess);

xlApp.DisplayAlerts = false;
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlApp = null;
xlApp = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();

Process processo = null;
try
{                   
    processo = Process.GetProcessById((int)idProcess);
}
catch { }

if (processo != null)
    processo.Kill();
0 голосов
/ 08 июля 2013
//Quit Excel application
eApp.Quit();

//Release COM objects (every object you used in eApp,like workbooks, Workbook, Sheets, Worksheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;

// Force garbage collector cleaning
GC.Collect();
0 голосов
/ 01 мая 2013

Tagore Peethala - простое решение и работает. В основном убедитесь, что WorkBook.CLOSE .. затем ExcelApplication.QUIT ... затем просто найдите экземпляр Excel, работающий без каких-либо открытий, и закройте его.

myExcelWorksheet = null;
if (myExcelWorkbook != null)
                {
                    myExcelWorkbook.Close();
                    myExcelWorkbook = null;
                }
                if (myExcelApp != null)
                {
                    myExcelApp.Quit();
                    myExcelApp = null;
                }
                foreach (System.Diagnostics.Process myProcess in System.Diagnostics.Process.GetProcessesByName("Excel"))
                {
                    if (myProcess.MainWindowTitle == "")
                    {
                        myProcess.Kill();
                    }
                }
0 голосов
/ 16 июля 2009

После ExcelApplication.Quit () добавьте следующий код.

Это убьет приложение Excel из процесса.

            Process[] Proc = Process.GetProcessesByName("Excel");
            foreach (Process p in Proc)
            {
                if (p.MainWindowTitle == "")
                    p.Kill();
            }
0 голосов
/ 27 ноября 2008

Использовать блок использования

Using eApp As New Excel.Application
  Using w As Excel.Workbook
    w = eApp.Workbooks.Open( "path.xls", ReadOnly:=True)
    .. Processing Code ..
    //Attempts at killing the excel application
    w.Close()
    eApp.Workbooks.Close()
    eApp.Quit()
  End Using
End Using

Аналогично блоку try / finally с удалением в finally, он автоматически удалит Excel.Application и Excel.Workbook.

Как уже упоминалось в другом посте, System.Runtime.InteropServices.Marshal.ReleaseComObject (eApp) также может понадобиться ????

0 голосов
/ 26 ноября 2008

Я опубликовал решение этой проблемы несколько дней назад: Уничтожение Excel.EXE на сервере

Тот же метод, который упоминает StingyJack; единственный, кого я знаю, чтобы действительно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...