无法杀死Excel进程

我正在使用下面的代码来做一些复制和粘贴excel文件:

Imports Excel = Microsoft.Office.Interop.Excel Imports System.IO Imports System.Runtime.InteropServices Private Sub btnCombine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCombine.Click Dim xlAppSource As New Excel.Application Dim xlAppTarget As New Excel.Application Dim xlWbSource As Excel.Workbook Dim xlWbTarget As Excel.Workbook Dim xlsheetSource As Excel.Worksheet Dim xlsheetTarget As Excel.Worksheet Dim xlRangeSource As Excel.Range Dim xlRangeTarget As Excel.Range Dim Progress As Integer = 0 pbrProgress.Minimum = 0 pbrProgress.Maximum = amountOfFiles btnCombine.Enabled = False btnSelect.Enabled = False pbrProgress.Visible = True getSaveLocation() MakeExcelFile() 'loop through all excel files to get the required data For i = 0 To amountOfFiles - 1 Dim CurrentFile As String = strFileNames(i) Dim IntAmountOfRows As Integer = amountOfRows(CurrentFile) Dim intStartOfEmptyRow As Integer = amountOfRows(SummaryLocation) xlAppSource.DisplayAlerts = False xlAppTarget.DisplayAlerts = False 'Set current workbook xlWbSource = xlAppSource.Workbooks.Open(CurrentFile) xlWbTarget = xlAppTarget.Workbooks.Open(SummaryLocation) 'set current worksheet xlsheetSource = xlWbSource.ActiveSheet xlsheetTarget = xlWbTarget.ActiveSheet 'copy range of data from source to target file xlRangeSource = xlsheetSource.Range("A2:k" & IntAmountOfRows) xlRangeSource.Copy() xlRangeTarget = xlsheetTarget.Range("A" & intStartOfEmptyRow) xlRangeTarget.PasteSpecial(Excel.XlPasteType.xlPasteValues) 'save summary file before closing xlsheetTarget.SaveAs(SummaryLocation) 'updating progress bar Progress = Progress + 1 pbrProgress.Value = Progress Next 'close excel xlWbSource.Close(True) xlWbTarget.Close(True) xlAppSource.Quit() xlAppTarget.Quit() xlAppSource.DisplayAlerts = True xlAppTarget.DisplayAlerts = True 'Cleanup Marshal.ReleaseComObject(xlAppSource) Marshal.ReleaseComObject(xlAppTarget) Marshal.ReleaseComObject(xlWbSource) Marshal.ReleaseComObject(xlWbTarget) Marshal.ReleaseComObject(xlsheetSource) Marshal.ReleaseComObject(xlsheettarget) Marshal.ReleaseComObject(xlRangeSource) Marshal.ReleaseComObject(xlRangeTarget) xlAppSource = Nothing xlAppTarget = Nothing xlWbSource = Nothing xlWbTarget = Nothing xlsheetSource = Nothing xlsheetTarget = Nothing xlRangeSource = Nothing xlRangeTarget = Nothing MsgBox("Samenvoegen compleet") init() End Sub 

我已经尝试了所有的解决scheme:

  • 永远不要在一条线上使用2点
  • 我曾尝试使用marshall.ReleaseComObject
  • 我曾尝试将对象设置为“Nothing”

但是,每次运行应用程序时,都会有10-20个excel进程在运行。

 Option Explicit Sub Main() Dim xlApp As Excel.Application Set xlApp = New Excel.Application xlApp.Visible = False xlApp.DisplayAlerts = False Dim xlWb As Workbook Set xlWb = xlApp.Workbooks.Open("C:\...\path") Dim xlSht As Worksheet Set xlSht = xlWb.Sheets(1) xlSht.Range("A1") = "message from " & ThisWorkbook.FullName xlWb.Saved = True xlWb.Save xlWb.Close xlApp.Quit End Sub 

每次都适用于我,不会在任务pipe理器中留下任何Excel进程。

注意:如果你的代码在某个时候中断了,而且你没有正确处理已经打开的对象,那么它们只会挂在任务pipe理器的进程选项卡中。 如果你没有在你的代码中实现error handling,那么从这里开始。

只是考虑这个替代

 Option Explicit Sub Main() On Error GoTo ErrHandler Dim xlApp As Excel.Application Set xlApp = New Excel.Application xlApp.Visible = False xlApp.DisplayAlerts = False Dim xlWb As Workbook Set xlWb = xlApp.Workbooks.Open("C:\...\path") Dim xlSht As Worksheet Set xlSht = xlWb.Sheets(1) xlSht.Range("A1") = "message from " & ThisWorkbook.FullName xlWb.Saved = True xlWb.Save xlWb.Close xlApp.Quit Exit Sub ErrHandler: xlWb.Saved = True xlWb.Save xlWb.Close xlApp.Quit End Sub 

The Interop Marshal release doesn't always work because Excel XP and lower suck at releasing. I had to use your loop, but replace the Process.Close() and Process.Quit() with Process.Kill(). Works like a charm. Just be careful that you want ALL versions of excel.exe to be killed, because they will.

我使用这个:

 Workbook.Save() Workbook.Close() Application.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(Application) Worksheet = Nothing Workbook = Nothing Application = Nothing Dim proc As System.Diagnostics.Process For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL") proc.Kill() Next 

当您对Excel Interop执行任何操作时,它会创build一个新的过程。

杀死所有Excel进程的问题是,你可能会杀死一个正在使用的进程。 你可以杀死所有已经运行了一段时间的进程(即从某个时间戳开始):

 Dim proc As System.Diagnostics.Process Dim info As ManagementObject Dim search As New ManagementObjectSearcher("SELECT ProcessId FROM Win32_process WHERE caption = 'Excel'") For Each info In search.Get() 'The string will give you the time that the process started 'You can then subtract that from the current time to see if you want to kill the process Dim TheString As String = info.GetText(TextFormat.Mof).ToString 'Kill the process according to its ID proc = System.Diagnostics.Process.GetProcessById(Mid$(TheString, _ (Len(TheString) - 8), 4)) proc.CloseMainWindow() proc.Refresh() If proc.HasExited Then GoTo NoKill proc.Kill() NoKill: Next 

你需要添加:

 Imports System.Management 

并将“System.Management”的参考添加到您的项目中。

您可以从Excel.Application hwnd获取进程ID,并使用它来安全地终止进程。