vb.net 无法杀死excel进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19224099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unable to kill excel processes
提问by Gutanoth
I am using the followiwing code to do some copying and pasting with excel files:
我正在使用以下代码对 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
I have tried every solution given on SO:
我已经尝试了 SO 上给出的所有解决方案:
- Never use 2 points on a line
- I have tried using marshall.ReleaseComObject
- I have tried setting the objects to "Nothing"
- 切勿在一条线上使用 2 个点
- 我曾尝试使用 marshall.ReleaseComObject
- 我尝试将对象设置为“无”
However, everytime I run the application, there will be 10-20 excel processes still running.
但是,每次运行该应用程序时,都会有 10-20 个 excel 进程仍在运行。
回答by
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
Works for me every single time and does not leave any Excel processes hanging in the task manager.
每次都对我有用,并且不会在任务管理器中留下任何挂起的 Excel 进程。
Note:if your code breaks at some point and you do not handle the already opened objects properly then they will just hang in the processes tab in the Task Manager. If you haven't implemented error handling in your code then start here.
注意:如果您的代码在某个时候中断,并且您没有正确处理已经打开的对象,那么它们只会挂在任务管理器的进程选项卡中。如果您尚未在代码中实现错误处理,请从此处开始。
just consider this as alternative
只考虑这个作为替代
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
回答by coder
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.
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.
I use this:
我用这个:
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
回答by Daniel Gee
When you do anything with the Excel Interop, it creates a new process.
当您使用 Excel Interop 执行任何操作时,它会创建一个新进程。
The problem with killing all Excel processes is that you may kill a process that you are working with. You can kill all processes which have been running for a certain length of time (i.e. from a certain timestamp) with:
终止所有 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
You'll need to add:
您需要添加:
Imports System.Management
and add the reference for the 'System.Management' to your project.
并将“System.Management”的引用添加到您的项目中。
回答by Rob
You can obtain the process ID from the Excel.Application hwnd and use that to kill the process safely.
您可以从 Excel.Application hwnd 获取进程 ID 并使用它来安全地终止进程。

