2011-04-20 94 views
4

我创建了下面的类来打开并收集excel文件中工作表的名称。它在打开文件并返回每个单独工作表的名称时应该如此。不幸的是,我无法关闭文件。这会使Excel.exe进程挂起。即使在我试图在这门课的最后关闭它,这个过程仍然会挂起。我必须手动转到Windows任务管理器并杀死该进程,然后才能再次使用该文件。即使我退出应用程序,它仍然在外面。任何关于如何从代码中杀死这个过程的建议?无法关闭从VB.NET应用程序的Excel进程

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 

回答

4

我以前碰到这个问题为好,我记得的解决办法是呼吁所有的来自办公室库中的对象的Marshal.ReleaseComObject(Object obj)Marshal.FinalReleaseComObject(Object obj)。尽管如此,我可能很容易出错。祝你好运,办公自动化是一个巨大的痛苦。

+0

这工作,我不得不释放一个Excel.Application,Excel.Workbook和Excel.Worksheet过程之前会消失 – rross 2011-05-02 18:14:38

0

这是通过自动化处理Excel时使用的清理代码。正确清理是非常重要的,否则这个过程会像你所看到的那样挂起。我假设你通过桌面应用程序而不是Web应用程序来完成此操作。这通常在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); 
3

对于每个参考尝试添加;

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

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

+0

这是正确的。在[相关问题]上查看我的回答(http://stackoverflow.com/questions/5627560/killing-excel-e xe-process-from-c-in-a-windows-service /),但在C#中。 – dotNetkow 2011-04-20 19:07:23

0

这不是专门针对您的Excel的问题;但你可以使用名称杀死一个进程...

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

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

这将杀死所有匹配特定名称的进程。

你可能想尝试加入 的Excel =无 ,看看是否能清除了问题(你能避免强行杀死进程。

0

我会修改你的代码的端部像这样,纠正了一些问题,可能导致您的问题!

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