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 会看到这一点并纠正我们!
我一直在寻找这个问题,但似乎找不到与我的问题完全匹配的问题。
我正在创建一个新的 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 会看到这一点并纠正我们!