简体   繁体   English

无法从VB.NET应用程序关闭Excel进程

[英]Unable to close Excel process from VB.NET app

I created the class below to open and gather the names of worksheets in an excel file. 我创建了下面的类来打开并收集excel文件中工作表的名称。 It does as it should in opening the file and returning the names of the each individual worksheet. 它在打开文件并返回每个单独工作表的名称时应该这样做。 Unfortunatly, I'm unable to close the file. 不幸的是,我无法关闭文件。 This keeps the Excel.exe process hanging. 这使Excel.exe进程保持挂起状态。 Even after I attempt to close it at the bottom of this class the process still hangs. 即使我试图在这个类的底部关闭它,这个过程仍然会挂起。 I have to manually goto Windows Task Manager and kill the process before I can use the file again. 在我再次使用该文件之前,我必须手动转到Windows任务管理器并终止该过程。 Even if I exit out of the application it still is out there. 即使我退出应用程序,它仍然在那里。 Any suggestion on how to kill this process from the code? 关于如何从代码中删除此进程的任何建议?

Imports Excel = Microsoft.Office.Interop.Excel

Public Class ExcelWrapper

Dim strTypeSelection As String = String.Empty
Dim strFilePath As String = String.Empty

Function GetWorksheetsByName(ByVal strfilePath As String) As Array

    Dim xlsApp As Excel.Application
    Dim xlsWorkBook As Excel.Workbook

    xlsApp = New Excel.Application
    xlsWorkBook = xlsApp.Workbooks.Open(strfilePath)
    Dim intWsCount As Integer = xlsApp.Worksheets.Count

    Dim sarWorksheetName(intWsCount - 1) As String

    Dim i As Integer = 0
    'gathers the names off all the worksheets 
    For Each totalWorkSheets In xlsApp.Worksheets
        sarWorksheetName(i) = totalWorkSheets.Name
        i += 1
    Next totalWorkSheets

    xlsWorkBook.Close(strfilePath)
    xlsApp.DisplayAlerts = False
    xlsApp.Quit()

    Return sarWorksheetName
End Function

End Class

I've run into this issue before as well, and as I recall the solution was to call Marshal.ReleaseComObject(Object obj) or Marshal.FinalReleaseComObject(Object obj) on all of the objects that the come from the Office libraries. 我之前也遇到过这个问题,并且我记得解决方案是在来自Office库的所有对象上调用Marshal.ReleaseComObject(Object obj)Marshal.FinalReleaseComObject(Object obj) I could very easily be wrong though. 我很容易就错了。 Good luck, Office automation is a huge pain. 祝你好运,办公自动化是一个巨大的痛苦。

For each reference try adding; 对于每个参考尝试添加;

System.Runtime.InteropServices.Marshal.ReleaseComObject(xxx)
xxx = nothing

( http://support.microsoft.com/kb/317109 ) http://support.microsoft.com/kb/317109

From http://www.experts-exchange.com/Programming/Misc/Q_24049269.html 来自http://www.experts-exchange.com/Programming/Misc/Q_24049269.html

' after creating it, but before operating on it
xlsApp.Application.DisplayAlerts = False

Here is cleanup code that I use when working with Excel through Automation. 这是我通过自动化使用Excel时使用的清理代码。 It is essential you clean up properly or the process will hang as you are seeing. 您必须正确清理,否则过程会因您看到而挂起。 I assume you are doing this through a desktop application and not a web app. 我假设您通过桌面应用程序而不是Web应用程序执行此操作。 This is usually done in a finally block and the sample is c# but I think you should be able to adapt it to your needs. 这通常在finally块中完成,样本是c#,但我认为您应该能够根据您的需要进行调整。

 GC.Collect();
 GC.WaitForPendingFinalizers();


 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(range);
 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sheet);
 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(book);

 WB.Close(false, Type.Missing, Type.Missing);

 Excel.Quit();
 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(Excel);

This is not specific to your Excel issue; 这不是特定于您的Excel问题; but you can kill a process by name using... 但是您可以使用名称来杀死进程...

Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName("WhateverYouWant")

For Each p As Process In pProcess
    p.Kill()
Next

That will kill all processes that match the particular name. 这将终止与特定名称匹配的所有进程。

You might want to try adding Excel = Nothing to see if that clears up the issue (and you can avoid forcefully killing the process'. 您可能想尝试添加Excel = Nothing以查看是否可以解决问题(并且您可以避免强行终止该进程'。

I would modify the end part of your code like so, to correct some issues that may be causing your problem: 我会像这样修改代码的结尾部分,以纠正可能导致问题的一些问题:

For Each totalWorkSheets as Excel.Worksheet In xlsWorkBook.Worksheets 'not xlsApp.Worksheets
   sarWorksheetName(i) = totalWorkSheets.Name
   i += 1
Next totalWorkSheets

xlsWorkBook.Close Savechanges:=False 
set xlsWorkBook = Nothing
xlsApp.Quit()
set xlsApp = Nothing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM