Я видел много статей и вопросов о том, как быть уверенным, что Excel действительно завершает работу, когда вы этого хотите, и процесс не остается в живых. Вот статья базы знаний с описанием проблемы и рекомендуемым решением Microsoft. По сути:
'close files
'Quit Excel
xlApp.quit()
'Release and collect garbage
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
GC.Collect()
GC.WaitForPendingFinalizers()
Многие не рекомендуют убивать процесс; См. Как правильно очистить объекты взаимодействия Excel и Общие сведения о сборке мусора в .NET
С другой стороны, многие люди не рекомендуют использовать GC.Collect. См. Что плохого в использовании GC.Collect ()?
По моему опыту, прекращение процесса - это самый быстрый и простой способ убедиться, что Excel больше нет. Мой код убивает только тот процесс, который он запускает, и никакой другой. Я обязательно закрываю все открытые книги, выхожу из приложения и освобождаю объект xlApp. Наконец, я проверяю, жив ли процесс, и если да, то убиваю его.
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
End Function
Sub testKill()
'start the application
Dim xlApp As Object = CreateObject("Excel.Application")
'do some work with Excel
'close any open files
'get the window handle
Dim xlHWND As Integer = xlApp.hwnd
'this will have the process ID after call to GetWindowThreadProcessId
Dim ProcIdXL As Integer = 0
'get the process ID
GetWindowThreadProcessId(xlHWND, ProcIdXL)
'get the process
Dim xproc As Process = Process.GetProcessById(ProcIdXL)
'Quit Excel
xlApp.quit()
'Release
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
'set to nothing
xlApp = Nothing
'kill the process if still running
If Not xproc.HasExited Then
xproc.Kill()
End If
End Sub
Я видел, как многие люди говорят, что убивать процесс - это плохо, но я не видел качественных ответов о том, почему. Особенно после того, как мы убедились, что файлы закрыты, Excel завершил работу, и мы завершим только тот процесс, который мы начали. Мой вопрос в том, каковы потенциальные проблемы с отключением процесса Excel. Это вредит производительности? Это навредит Excel?
Многие также скажут, что с хорошим кодом мне не нужно убивать процесс. Может быть, но это не отвечает на вопрос «Почему плохо убивать процесс?» После закрытия файлов, выхода из Excel и освобождения объектов; почему было бы плохо просто убедиться, что процесс завершен?
Изменить: также, что на самом деле остается после выхода из Excel? Если Excel был виден, он, похоже, завершил работу нормально, исчезнув из поля зрения и с панели задач. Так действительно ли Excel закрылся или нет. Мне кажется, что Excel действительно завершил работу и у нас работает только пустая оболочка процесса. Кто-нибудь может это прокомментировать?
Изменить: мне интересно отметить, что сборщик мусора (он же сборщик мусора) через GC.Collect () GC.WaitForPendingFinalizers () фактически освобождает оболочку процесса, которая остается после выхода Excel. Подтверждает ли это мое предположение, что пустая оболочка процесса на самом деле является мусором?
Изменить: только что нашел отличный веб-сайт по проблеме: 50 способов убить Excel
GC.Collect()
, и приложение должно быть закрыто либо пользователем, либо путем вызоваQuit
, и если пользователь отменяет закрытие, это не считается. Когда я все это делаю, я получаю лишние excel.exes только при отладке (поскольку остановка выполнения не очистит). - person Dave Cousineau   schedule 22.07.2013