无法杀死excel进程

时间:2013-10-07 11:48:40

标签: vb.net visual-studio-2010 excel process

我正在使用followiwing代码对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

我尝试过在SO上给出的每个解决方案:

  • 切勿在一条线上使用2个点
  • 我尝试过使用marshall.ReleaseComObject
  • 我尝试将对象设置为“Nothing”

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

4 个答案:

答案 0 :(得分:3)

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

每次都为我工作,不会在任务管理器中挂起任何Excel进程。

注意:如果您的代码在某些时候中断并且您没有正确处理已经打开的对象,那么它们将只挂在任务管理器的进程选项卡中。如果您尚未在代码中实施错误处理,请启动here

将此视为替代

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

当您使用Excel Interop执行任何操作时,它会创建一个新进程。

杀死所有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”的引用添加到项目中。

答案 3 :(得分:0)

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