VB.Net - 后台 Excel 进程在关闭文件后重新打开

VB.Net - Background Excel process REOPENS after closing file

我一直在寻找这个问题,但似乎找不到与我的问题完全匹配的问题。

我正在创建一个新的 excel 文件,用数据填充它,并将其显示给用户。在监视任务管理器时,我可以看到一旦文件被创建并为用户打开,后台进程就会按预期消失。 (主要进程仍然 运行 因为文件是打开的。)

我遇到的问题是一旦用户关闭文件,Excel后台进程就会重新出现在列表中并且不会消失,直到程序(那个生成文件)已关闭。

这是我正在使用的清理工具;

Dim xlObject As New Excel.Application
Dim xlBook As Excel.Workbook = Nothing 
Dim xlSheet As Excel.Worksheet = Nothing 

xlBook = xlObject.Workbooks.Add
xlSheet = xlBook.Worksheets(1)

'Fill data and do some formatting 

xlBook.SaveAs("FileName")
xlObject.Visible = True 
    
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
xlSheet = Nothing 
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
xlBook = Nothing 
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlObject)
xlObject = Nothing

有什么我想念的吗?为什么后台进程还在继续,只有在创建程序关闭后才会消失?

这是使用 Visual Studios 2013, Office 365 Excel, 和 Windows 10 Pro

你看,在 Interop 中,你应该避免通过另一个对象访问一个对象,例如

xlBook = xlObject.Workbooks.Add

这叫做两点法则。原因是 Workbooks 对象随后在 .NET 中被引用并被孤立(并且也应该被杀死,因为你有其他三个)

所以引用工作簿,然后也将其删除。

Dim xlApp As New Excel.Application()
Dim xlBooks = xlApp.Workbooks
Dim xlBook = xlBooks.Add
Dim xlSheet = DirectCast(xlBook.Worksheets(1), Excel.Worksheet)

Try
    xlBook.SaveAs("FileName.xlsx")
    xlApp.Visible = True
Finally
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
    xlSheet = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
    xlBook = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
    xlBooks = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
    xlApp = Nothing
End Try

而且,我一直为此苦苦挣扎,因为据 Whosebug 上 vb.net 的杰出专家 HansPassant the two dot rule is just superstition 所说,正如他所说,“继续忽略 [两个点规则],这是胡说八道,只会引起悲伤”但是对于你的问题,我只能通过遵循两点规则而不是使用汉斯的解决方案来使其工作:

GC.Collect()
GC.WaitForPendingFinalizers()

也许 Hans 会看到这一点并纠正我们!