【问题标题】:Excel still running after close vb.net app关闭 vb.net 应用程序后 Excel 仍在运行
【发布时间】:2018-05-17 10:34:08
【问题描述】:

我在关闭 Excel 文件时遇到了一些问题。我正在做一个程序,它可以打开一些 Excel 文件,使用这些信息然后关闭它们。
我尝试了一些不同的代码,但它们不起作用,因为EXCEL 进程仍在运行。

我的第一个代码:

Dim aplicacaoexcel As New Excel.Application
Dim livroexcel As Object
Dim folhaexcel As Excel.Worksheet

livroexcel = aplicacaoexcel.Workbooks.Open("C:\Users\LPO1BRG\Desktop\Software Fiabilidade\Tecnicos.xlsx", UpdateLinks:=False, ReadOnly:=False, Password:="qmm7", WriteResPassword:="qmm7")
folhaexcel = livroexcel.sheets("Folha1")

aplicacaoexcel.DisplayAlerts = False
aplicacaoexcel.Visible = False
folhaexcel = Nothing
livroexcel.Close()
livroexcel = Nothing
aplicacaoexcel.Quit()
aplicacaoexcel = Nothing

然后我添加了这个:System.GC.Collect(),但它仍然没有关闭 Excel 进程。

现在我正在尝试这个:

Dim process() As Process = system.Diagnostics.Process.GetProcessesByName("EXCEL")

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

实际上,这个可以工作,但它会关闭所有 Excel 文件(即使是那些没有被我的程序打开的文件)。

如何仅关闭程序打开的 Excel 文件? :)

【问题讨论】:

标签: excel vb.net office-interop close-application


【解决方案1】:

释放Excel.Application Interop COM 对象比其他Office Interop 对象有点棘手,因为有些对象是在您不知情的情况下创建的,并且必须在主应用程序真正关闭之前释放它们。

这些对象包括:

  • Excel.Application
  • Excel.Application.WorkBooks 集合
  • WorkBooks 集合已打开 WorkBook
  • 工作簿工作表集合
  • Sheets 集合引用了 Worksheet

必须全部释放这些对象才能终止 EXCEL 进程。

一个简单的解决方案是对所有 COM 对象使用显式声明/赋值:

Dim ExcelApplication As New Microsoft.Office.Interop.Excel.Application()
Dim ExcelWorkbooks As Workbooks = ExcelApplication.Workbooks
Dim MyWorkbook As Workbook = ExcelWorkbooks.Open("[WorkBookPath]", False)
Dim worksheets As Sheets = MyWorkbook.Worksheets
Dim MyWorksheet As Worksheet = CType(worksheets("Sheet1"), Worksheet)

完成后,将它们全部释放:

Imports System.Runtime.InteropServices

Marshal.ReleaseComObject(MyWorksheet)
Marshal.ReleaseComObject(worksheets)

MyWorkbook.Close(False)   '<= False if you don't want to save it!
Marshal.ReleaseComObject(MyWorkbook)

ExcelWorkbooks.Close()
Marshal.ReleaseComObject(ExcelWorkbooks)

ExcelApplication.Quit()
Marshal.FinalReleaseComObject(ExcelApplication)

Marshal.CleanupUnusedObjectsInCurrentContext()

【讨论】:

    【解决方案2】:

    试试workbook.Saveworkbook.close之类的东西

    【讨论】:

      【解决方案3】:

      我的 VB 有点生疏,现在无法访问 Visual Studio 来测试它,但我会尝试从内存中编写代码。

      您遇到的问题是,将对象设置为 Nothing 仍然会将对象分配在内存中,并且不会完全处理该对象。即使对象的 Close() 和 Quit() 方法仍将其分配在内存中,以防程序稍后需要再次访问它们。 Kill() 方法之所以有效,是因为它只是终止了在内存中运行的 Excel 应用程序,该应用程序会关闭所有打开的 Excel 文档以及 COM 对象使用的文档。您要做的是处理您的应用程序正在使用的特定 COM 对象。

      尝试在您的代码中进行此更改。

      Dim aplicacaoexcel As New Excel.Application
      Dim livroexcel As Object
      Dim folhaexcel As Excel.Worksheet
      
      livroexcel = aplicacaoexcel.Workbooks.Open("C:\Users\LPO1BRG\Desktop\Software Fiabilidade\Tecnicos.xlsx", UpdateLinks:=False, ReadOnly:=False, Password:="qmm7", WriteResPassword:="qmm7")
      folhaexcel = livroexcel.sheets("Folha1")
      
      aplicacaoexcel.DisplayAlerts = False
      aplicacaoexcel.Visible = False
      
      DisposeComObj(folhaexcel)
      DisposeComObj(livroexcel)
      DisposeComObj(aplicacaoexcel)
      

      然后将以下内容也添加到您的应用程序中。

      Private Sub DisposeComObj(ByRef Reference As Object)
          Try        
              Do Until _
              System.Runtime.InteropServices.Marshal.ReleaseComObject(Reference)<=0
              Loop
          Catch
          Finally
              Reference = Nothing
          End Try
      End Sub
      

      希望我的记忆对我有帮助。我已经一年多没有用 VB 或 C# 写过任何代码了,感觉很不习惯。我只看到你的问题是因为我点击了错误的链接,并记得我在开始编程时曾经如何与垃圾收集作斗争。

      【讨论】:

        猜你喜欢
        • 2013-02-03
        • 2011-04-02
        • 2021-05-17
        • 1970-01-01
        • 1970-01-01
        • 2020-01-03
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多