在VB.NET中closures后,Excel在任务pipe理器中保持打开状态

我创build了一个在VB.NET中创build一对Excel电子表格的应用程序

我遇到的问题是,我不能让Excel完全退出。

我使用隐藏的Excel创build和填充VB.NET中的工作簿,该过程(Microsoft Excel)在任务pipe理器的后台进程中显示

一旦完成,我就可以看到Excel,并且程序移动到应用程序。

然后,当我closuresExcel时,该过程将返回到后台进程。

任何想法我做错了什么?

码:

Dim oExcel As Excel.Application = Nothing Dim oWorkbook As Excel.Workbook = Nothing Dim oWorksheet As Excel.Worksheet = Nothing Dim oRange As Excel.Range = Nothing oExcel = CreateObject("Excel.Application") oExcel.DisplayAlerts = False oExcel.Visible = False oWorkbook = oExcel.Workbooks.Add oWorksheet = oWorkbook.ActiveSheet 'Populate, format, etc. oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales.xlsx") oExcel.Visible = True oRange = Nothing oWorksheet = Nothing oWorkbook = Nothing ReleaseObject(oExcel) Public Sub ReleaseObject(ByVal obj As Object) Dim iValue As Integer = 0 Try Do iValue = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) Loop While iValue > 0 Catch ex As Exception RaiseError("", "modGeneral." & "." & System.Reflection.MethodBase.GetCurrentMethod().Name, Err.Number, Err.Description) obj = Nothing Finally GC.Collect() End Try End Sub 

更新10/31/2016:

好吧,现在我真的很困惑。

采取下面的build议使用此代码,我可以让Excel彻底退出一个警告:

  GC.Collect() GC.WaitForPendingFinalizers() System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) : oWorksheet = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) : oWorkbook = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) : oExcel = Nothing 

但是,我的代码正在创build两个工作簿。 创build每个工作簿的代码除了SQL以外都是相同的。 如果用户打勾chkA清理代码不起作用。 如果他们检查chkB它确实工作。 如果他们检查两个,它不起作用。 我已经在下面列出了完整的代码:

  Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click Dim oExcel As Excel.Application = Nothing Dim oWorkbook As Excel.Workbook = Nothing Dim oWorksheet As Excel.Worksheet = Nothing Dim drSystem As SqlClient.SqlDataReader = Nothing Dim sSQL As String = "" Dim iRowCount As Integer = 2 Try If Not Me.chkA.Checked And Not Me.chkB.Checked Then MsgBox("Select A, B or both before continuing.", vbInformation) Exit Try End If Me.Cursor = Cursors.WaitCursor Me.lblStatus.Text = "Exporting sales..." oExcel = CreateObject("Excel.Application") oExcel.DisplayAlerts = False oExcel.Visible = False If Me.chkA.Checked Then oWorkbook = oExcel.Workbooks.Add oWorksheet = oWorkbook.ActiveSheet oWorksheet.Cells(1, 1).Value = "Ship date" oWorksheet.Cells(1, 2).Value = "Customer" oWorksheet.Cells(1, 3).Value = "Invoice" oWorksheet.Cells(1, 4).Value = "Purchase order" oWorksheet.Cells(1, 5).Value = "Railcar" oWorksheet.Cells(1, 6).Value = "Weight" oWorksheet.Cells(1, 7).Value = "Total" oWorksheet.Cells(1, 8).Value = "Member purchase order" sSQL = "SELECT FORMAT(i.ship_date, N'MM/dd/yyyy') AS ship_date, " sSQL += "i.customer_no, " sSQL += "i.invoice_number, " sSQL += "i.customer_purchase_order_no, " sSQL += "r.railcar_number, " sSQL += "r.weight, " sSQL += "r.total, " sSQL += "i.member + N'-' + i.member_purchase_order_no AS member_purchase_order_no " sSQL += "FROM Invoices i " sSQL += "JOIN Railcars r " sSQL += "ON i.invoice_number = r.invoice_number " sSQL += "WHERE i.ship_date BETWEEN N'" & Format(Me.dtpStartDate.Value, "MM/dd/yyyy") & "' AND N'" & Format(Me.dtpEndDate.Value, "MM/dd/yyyy") & "' AND " sSQL += "invoice_type = N'A' " sSQL += "ORDER BY i.customer_no, " sSQL += "i.ship_date, " sSQL += "r.railcar_number" drSystem = modGeneral.drRunSQL(sSQL, CommandType.Text) Do While drSystem.Read oWorksheet.Cells(iRowCount, 1).Value = drSystem("ship_date") oWorksheet.Cells(iRowCount, 2).Value = drSystem("customer_no") oWorksheet.Cells(iRowCount, 3).Value = drSystem("invoice_number") oWorksheet.Cells(iRowCount, 4).Value = drSystem("customer_purchase_order_no") oWorksheet.Cells(iRowCount, 5).Value = drSystem("railcar_number") oWorksheet.Cells(iRowCount, 6).Value = drSystem("weight") oWorksheet.Cells(iRowCount, 7).Value = drSystem("total") oWorksheet.Cells(iRowCount, 8).Value = drSystem("member_purchase_order_no") iRowCount += 1 Loop drSystem.Close() With oWorksheet.Range("A1", "J1") .Font.Bold = True .EntireColumn.AutoFit() End With oWorksheet.Range("D1").EntireColumn.HorizontalAlignment = Excel.Constants.xlLeft With oWorksheet.Range("F1") .EntireColumn.HorizontalAlignment = Excel.Constants.xlRight .EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)" End With With oWorksheet.Range("G1") .EntireColumn.HorizontalAlignment = Excel.Constants.xlRight .EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)" End With oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales-a.xlsx") End If If Me.chkB.Checked Then iRowCount = 2 oWorkbook = oExcel.Workbooks.Add oWorksheet = oWorkbook.ActiveSheet oWorksheet.Cells(1, 1).Value = "Ship date" oWorksheet.Cells(1, 2).Value = "Customer" oWorksheet.Cells(1, 3).Value = "Invoice" oWorksheet.Cells(1, 4).Value = "Purchase order" oWorksheet.Cells(1, 5).Value = "Railcar" oWorksheet.Cells(1, 6).Value = "Weight" oWorksheet.Cells(1, 7).Value = "Total" oWorksheet.Cells(1, 8).Value = "Member purchase order" sSQL = "SELECT FORMAT(i.ship_date, N'MM/dd/yyyy') AS ship_date, " sSQL += "i.customer_no, " sSQL += "i.invoice_number, " sSQL += "i.customer_purchase_order_no, " sSQL += "r.railcar_number, " sSQL += "r.weight, " sSQL += "r.total, " sSQL += "i.member + N'-' + i.member_purchase_order_no AS member_purchase_order_no " sSQL += "FROM mxInvoices i " sSQL += "JOIN mxRailcars r " sSQL += "ON i.invoice_number = r.invoice_number " sSQL += "WHERE i.ship_date BETWEEN N'" & Format(Me.dtpStartDate.Value, "MM/dd/yyyy") & "' AND N'" & Format(Me.dtpEndDate.Value, "MM/dd/yyyy") & "' AND " sSQL += "invoice_type = N'B' " sSQL += "ORDER BY i.customer_no, " sSQL += "i.ship_date, " sSQL += "r.railcar_number" drSystem = modGeneral.drRunSQL(sSQL, CommandType.Text) Do While drSystem.Read oWorksheet.Cells(iRowCount, 1).Value = drSystem("ship_date") oWorksheet.Cells(iRowCount, 2).Value = drSystem("customer_no") oWorksheet.Cells(iRowCount, 3).Value = drSystem("invoice_number") oWorksheet.Cells(iRowCount, 4).Value = drSystem("customer_purchase_order_no") oWorksheet.Cells(iRowCount, 5).Value = drSystem("railcar_number") oWorksheet.Cells(iRowCount, 6).Value = drSystem("weight") oWorksheet.Cells(iRowCount, 7).Value = drSystem("total") oWorksheet.Cells(iRowCount, 8).Value = drSystem("member_purchase_order_no") iRowCount += 1 Loop drSystem.Close() With oWorksheet.Range("A1", "J1") .Font.Bold = True .EntireColumn.AutoFit() End With oWorksheet.Range("D1").EntireColumn.HorizontalAlignment = Excel.Constants.xlLeft With oWorksheet.Range("F1") .EntireColumn.HorizontalAlignment = Excel.Constants.xlRight .EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)" End With With oWorksheet.Range("G1") .EntireColumn.HorizontalAlignment = Excel.Constants.xlRight .EntireColumn.NumberFormat = "#,##0.00_);(#,##0.00)" End With oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales-b.xlsx") End If oExcel.Visible = True GC.Collect() GC.WaitForPendingFinalizers() System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) : oWorksheet = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) : oWorkbook = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) : oExcel = Nothing Catch ex As Exception RaiseError("", Me.Name & "." & System.Reflection.MethodBase.GetCurrentMethod().Name, Err.Number, Err.Description) Finally If Not drSystem Is Nothing Then If Not drSystem.IsClosed Then drSystem.Close() End If End Try Me.lblStatus.Text = "" Me.Cursor = Cursors.Default 

你需要在使用之后处理和释放excel对象。

即使在任务pipe理器中,为了closuresexcel,我使用了一个简单的代码:

Private Sub releaseObject(ByVal obj As Object) Try System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing Catch ex As Exception obj = Nothing Finally GC.Collect() End Try End Sub

它适用于我的应用程序

不幸的是,将variables设置为Nothing不会在互操作的情况下释放excel进程句柄。但是,如果您明确地释放了每个已经实例化的excel com对象引用,那么一旦excel被closures用户。 当我运行下面的代码并closures了excel时,这个过程不再是挂起的(我把oRange省略了,因为它还没有设置,释放一个没有任何exception的对象):

 Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim oExcel As Excel.Application = Nothing Dim oWorkbook As Excel.Workbook = Nothing Dim oWorksheet As Excel.Worksheet = Nothing oExcel = CreateObject("Excel.Application") oExcel.DisplayAlerts = False oExcel.Visible = False oWorkbook = oExcel.Workbooks.Add oWorksheet = oWorkbook.ActiveSheet 'Populate, format, etc. 'oWorkbook.SaveAs(Me.txtExportLocation.Text & "\sales.xlsx") oExcel.Visible = True System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorksheet) System.Runtime.InteropServices.Marshal.ReleaseComObject(oWorkbook) System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) Me.Close() End Sub End Class