2015-08-07 6 views
0

Я использую сообщество Visual Studio 2015 в C# и Office 2013 автономно.Не удается закрыть Excel.exe после его уничтожения из диспетчера задач

Приведенный ниже код работал, чтобы открыть и закрыть Excel. Затем я добавил код, чтобы открыть конкретный рабочий лист, как в примере 2 ниже. И это сработало, Excel закрыт правильно.

Затем я переехал, но забыл использовать ReleaseComObject для рабочего листа, и Excel остался открытым, поэтому я вручную закрыл его в диспетчере задач.

Теперь НИКАКИЕ из приведенных ниже примеров не работают. После того, как я случайно забыл выпустить COM-объект, Excel никогда не закрывается, если я не перезагружу свою машину.

Пример 1

private bool loadExcel() 
{ 
    // Open Excel 
    Excel.Application myApp = new Excel.Application(); 
    // Hide Excel 
    myApp.Visible = false; 
    GSIWorkbook = myApp.Workbooks.Open("D:\\Test.xlsx"); 
    // Cleanup 
    GSIWorkbook.Close(false); 
    // Manual disposal because of COM 
    while (System.Runtime.InteropServices.Marshal.ReleaseComObject(GSIWorkbook) != 0) 
    { } 

    myApp.Application.Quit(); 
    myApp.Quit(); 
    while (System.Runtime.InteropServices.Marshal.ReleaseComObject(myApp) != 0) 
    { } 

    myApp = null; 
    GSIWorkbook = null; 

    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    return true; 

} // End loadExcel 

Пример 2

private bool loadExcel() 
{ 
    // Open Excel 
    Excel.Application myApp = new Excel.Application(); 
    // Hide Excel 
    myApp.Visible = false; 
    GSIWorkbook = myApp.Workbooks.Open("D:\\Test.xlsx"); 

    for (int counter = 1; counter < 100; counter++) 
    { 
     try 
     { 
      GSIWorksheet = GSIWorkbook.Sheets[counter]; 
      if (GSIWorksheet.Name == _gsi2Sheet) 
       break; 
     } 
     catch 
     { 
      continue; 
     } 
    } 

    while (System.Runtime.InteropServices.Marshal.ReleaseComObject(GSIWorksheet) != 0) 
    { } 

    // Cleanup 
    GSIWorkbook.Close(false); 
    // Manual disposal because of COM 
    while (System.Runtime.InteropServices.Marshal.ReleaseComObject(GSIWorkbook) != 0) 
    { } 

    myApp.Application.Quit(); 
    myApp.Quit(); 
    while (System.Runtime.InteropServices.Marshal.ReleaseComObject(myApp) != 0) 
    { } 

    myApp = null; 
    GSIWorkbook = null; 

    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    return true; 
} // End loadExcel 
+0

ли вы имеете в виду VS сообщества? Visual Studio? – Grantly

+0

«Excel никогда не закрывается, если я не перезагружу свою машину». ... Кроме того, просто откройте диспетчер задач и убейте все оставшиеся процессы «excel.exe». –

+0

Как я уже говорил выше, я использую C#, а не VB, и я не использую «.Add» в любом месте. Убийство в диспетчере задач не является чистым решением, и использование proc.Kill() приведет к уничтожению всех экземпляров Excel. Я понимаю, что я мог обнаружить идентификатор процесса (PID), а затем убить только этот процесс. Но это тоже похоже на kluge. Должен быть чистый способ закрыть Excel после того, как я пройду через него. – OneWileyDog

ответ

3

Если вы показать нам свое полное использование Вашего объекта первенствовать, я уверен, вы найдете вы нарушаете правило 2 точек. Звучит абсурдно. Я знаю, но я думаю, что вы непреднамеренно создаете экземпляры объектов, которые не могут быть удалены Excel или GC, и затем он не может нормально закрыться. (Вызывается Время воспроизведения отзывной Упаковщики)

При использовании - говорят, - этот код:

xlWorkBook = xlApp.Workbooks.Add 

... вы на самом деле причиной проблемы. Вам нужно создать переменную, указывающую на Workbooks, и использовать ее прямо и утилизировать. Пример по ссылке:

Dim xlApp As New Excel.Application 
Dim xlWorkBooks As Excel.Workbooks = xlApp.Workbooks 
Dim xlWorkBook As Excel.Workbook = xlWorkBooks.Add() 

.... весь код, а затем

xlApp.Quit() 

If Not xlWorkBook Is Nothing Then 
    Marshal.FinalReleaseComObject (xlWorkBook) 
    xlWorkBook = Nothing 
End If 
If Not xlWorkBooks Is Nothing Then 
    Marshal.FinalReleaseComObject (xlWorkBooks) 
    xlWorkBooks = Nothing 
End If 
If Not xlApp Is Nothing Then 
    Marshal.FinalReleaseComObject (xlApp) 
    xlApp = Nothing 
End If 

xlApp.Quit() 

Смотрите здесь для подробностей:

http://www.siddharthrout.com/2012/08/06/vb-net-two-dot-rule-when-working-with-office-applications-2/

+0

Как я сказал выше, я использую C#, а не VB, и я не использую «.Add» в любом месте. Убийство в диспетчере задач не является чистым решением, и использование proc.Kill() приведет к уничтожению всех экземпляров Excel. Я понимаю, что я мог обнаружить идентификатор процесса (PID), а затем убить только этот процесс. Но это тоже похоже на kluge. Должен быть чистый способ закрыть Excel после того, как я пройду через него. – OneWileyDog

+0

Мне было все равно, как вы хотите убить Excel без использования QUIT в своем приложении. Я также не отвечаю на вопрос .ADD. Мой ответ диктует, что вы не можете - ни при каких обстоятельствах - использовать Runtime Callable Wrapper и ожидать элегантного закрытия Excel. «ПРАВИЛО» двух точек используется для любых методов и не только .ADD – Grantly

+0

Мой ответ не зависит от языка ... C#, VB.NET, VB6 ... любой язык, который вы выберете, будет иметь одинаковую проблему. Пожалуйста, разместите свои комментарии, имеющие отношение к предоставленному ответу, я заметил, что вы разместили это дважды, и я думал, что ваш комментарий был специфическим для моего ответа ... – Grantly

Смежные вопросы