Vb.net Marshal.ReleaseComObject未首先释放

Vb.net Marshal.ReleaseComObject未首先释放,vb.net,excel,object,Vb.net,Excel,Object,我正在做的这个项目是一张参考卡,它从excel文件中提取文本,从同一个搜索文件夹中提取图片。然后通过一个接一个地调用sub来“循环”进程,直到退出应用程序。参考卡应该每10分钟更新一次,方法是研究文件并重复这个过程。问题是,我希望代码打开文件,拉取,然后完全关闭文件,然后等待并重复。这样可以在下次更新之前编辑文件。相反,它说它仍在使用,意思是只读。即使我关闭了应用程序和visual Studio,它仍然显示仍在使用中。我必须在任务管理器中强制结束进程 使用封送。ReleaseComObject不

我正在做的这个项目是一张参考卡,它从excel文件中提取文本,从同一个搜索文件夹中提取图片。然后通过一个接一个地调用sub来“循环”进程,直到退出应用程序。参考卡应该每10分钟更新一次,方法是研究文件并重复这个过程。问题是,我希望代码打开文件,拉取,然后完全关闭文件,然后等待并重复。这样可以在下次更新之前编辑文件。相反,它说它仍在使用,意思是只读。即使我关闭了应用程序和visual Studio,它仍然显示仍在使用中。我必须在任务管理器中强制结束进程

使用
封送。ReleaseComObject
不起作用。代码启动Excel流程,完成代码,发布不起作用。在第二次循环并创建一个新流程(现在是2个Excel流程)后,该版本可以工作,但仅适用于新流程,而不是原始流程,并且每次循环都会继续请帮忙我一整天都在主演这部电影

下面的图片是在第一个创建的进程和第一个失败的对象释放之后,在代码的第二次“releaseObject(wbXl)”之前。在此之后,将发布第二个进程,但不会发布第一个进程,依此类推。请注意,如果应用程序关闭,第一个进程将结束

代码

Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices
Imports Excel = Microsoft.Office.Interop.Excel
Imports System.ComponentModel

Public Class Form1
Dim appXL As Excel.Application
Dim wbXls As Excel.Workbooks
Dim wbXl As Excel.Workbook
Dim shXL As Excel.Worksheet
Dim FldPath As String
Dim PartID As String
Dim RefCard As String
Dim timeUpDate As Double

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    'Dispaly Brembo Logo
    picLogo.SizeMode = PictureBoxSizeMode.StretchImage
    ReferenceCardDataPull()
End Sub

Private Sub Wait()
    Threading.Thread.Sleep(10000)
End Sub
Private Async Sub ReferenceCardDataPull()
    'Prepare For Load
    lblTimer.Text = "Updating"
    lblError.Visible = False

    'Read File Source with part number ******************
    PartID = ("19.N111.10")


    ' Start Excel and get Application object.
    appXL = CreateObject("Excel.Application")
    appXL.Visible = False

    'Open Reference Card*************************************************************************************
    FldPath = ("\\HOMESHARE01\Public\Kaizens\Kaizen 44 - Missing Parts\Reference Cards\Completed Reference Cards by Part Number" & "\" & PartID)
    If System.IO.Directory.Exists(FldPath) Then

        If System.IO.File.Exists(FldPath & "\" & PartID & ".xlsm") Then
            'wbXl = appXL.Workbooks.Open(FldPath & "\" & PartID & ".xlsm")**** Archive

            wbXls = appXL.Workbooks
            wbXl = wbXls.Open(FldPath & "\" & PartID & ".xlsm")
            shXL = wbXl.Worksheets("Sheet1")

            ' Copys Reference Card Data by Cell To App labels
            lblCODE.Text = shXL.Cells(6, 5).Value
            lblREV.Text = shXL.Cells(3, 5).Value
            lblDate.Text = shXL.Cells(9, 5).Value
            lblCustomer.Text = shXL.Cells(3, 1).Value
            lblPart.Text = shXL.Cells(6, 1).Value
            lblSpindleType.Text = shXL.Cells(9, 1).Value
            lblPaintType.Text = shXL.Cells(12, 1).Value
            lblDunnageType.Text = shXL.Cells(15, 1).Value
            lblPartsLayer.Text = shXL.Cells(3, 3).Value
            lblLayers.Text = shXL.Cells(6, 3).Value
            lblTotalParts.Text = shXL.Cells(9, 3).Value
            lblPackagingInstructs.Text = shXL.Cells(12, 3).Value
        Else
            lblCODE.Text = ("Error")
            lblREV.Text = ("Error")
            lblDate.Text = ("Error")
            lblCustomer.Text = ("Error")
            lblPart.Text = ("Error")
            lblSpindleType.Text = ("Error")
            lblPaintType.Text = ("Error")
            lblDunnageType.Text = ("Error")
            Lable49.Text = ("Error")
            lblLayers.Text = ("Error")
            lblTotalParts.Text = ("Error")
            lblPackagingInstructs.Text = ("Error")
            lblError.Visible = True

            ' Close objects**** Archive
            ' shXL = Nothing**** Archive
            ' wbXl.Close()**** Archive
            'appXL.Quit()**** Archive
            'appXL = Nothing**** Archive



        End If

    Else
        'File not found Error
        lblCODE.Text = ("Error")
        lblREV.Text = ("Error")
        lblDate.Text = ("Error")
        lblCustomer.Text = ("Error")
        lblPart.Text = ("Error")
        lblSpindleType.Text = ("Error")
        lblPaintType.Text = ("Error")
        lblDunnageType.Text = ("Error")
        Lable49.Text = ("Error")
        lblLayers.Text = ("Error")
        lblTotalParts.Text = ("Error")
        lblPackagingInstructs.Text = ("Error")
        lblError.Visible = True
    End If

    'Pulls pictures from designated part folder
    If System.IO.File.Exists(FldPath & "\" & "PicSpindle" & PartID & ".JPG") Then
        picSpindle.Image = Image.FromFile(FldPath & "\" & "PicSpindle" & PartID & ".JPG")
        picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
    Else
        picSpindle.SizeMode = PictureBoxSizeMode.StretchImage
    End If

    If System.IO.File.Exists(FldPath & "\" & "PicRotorTop" & PartID & ".JPG") Then
        picRotorTop.Image = Image.FromFile(FldPath & "\" & "PicRotorTop" & PartID & ".JPG")
        picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
    Else
        picRotorTop.SizeMode = PictureBoxSizeMode.StretchImage
    End If

    If System.IO.File.Exists(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG") Then
        picRotorBottom.Image = Image.FromFile(FldPath & "\" & "PicRotorBottom" & PartID & ".JPG")
        picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
    Else
        picRotorBottom.SizeMode = PictureBoxSizeMode.StretchImage
    End If

    If System.IO.File.Exists(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG") Then
        picDunnageFinal.Image = Image.FromFile(FldPath & "\" & "PicDunnageFinal" & PartID & ".JPG")
        picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
    Else
        picDunnageFinal.SizeMode = PictureBoxSizeMode.StretchImage
    End If

    If System.IO.File.Exists(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG") Then
        picDunnageLayer.Image = Image.FromFile(FldPath & "\" & "PicDunnageLayer" & PartID & ".JPG")
        picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
    Else
        picDunnageLayer.SizeMode = PictureBoxSizeMode.StretchImage
    End If

    ' Close objects
    wbXl.Close()
    wbXls.Close()
    appXL.Quit()
    'Release Objects
    releaseObject(shXL)
    releaseObject(wbXl)
    releaseObject(wbXl)
    releaseObject(wbXls)
    releaseObject(appXL)

    timeUpDate = 9
    tmrUpdate.Start()
    Application.DoEvents()
    Await Task.Run(Sub()
                       Wait()

                   End Sub)
    ReferenceCardDataPull()
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles tmrUpdate.Tick
    Dim hms = TimeSpan.FromSeconds(timeUpDate)
    Dim m = hms.Minutes.ToString
    Dim s = hms.Seconds.ToString

    If timeUpDate > 0 Then
        timeUpDate -= 1
        lblTimer.Text = (m & ":" & s)

    Else

        tmrUpdate.Stop()
        lblTimer.Text = "Preparing Update"

    End If

End Sub
Private Sub releaseObject(ByVal obj As Object)
    Try
        Dim intRel As Integer = 0
        Do
            intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        Loop While intRel > 0
        'MsgBox("Final Released obj # " & intRel)
    Catch ex As Exception
        MsgBox("Error releasing object" & ex.ToString)
        obj = Nothing
    Finally
        GC.Collect()
    End Try
End Sub
End Class

尝试修改代码以关闭excel以调用此函数:

Private Sub CloseExcel(ByRef xlApp As Excel.Application, xlWorkBook As Excel.Workbook, xlWorkSheet As Excel.Worksheet)
    Try
        xlWorkBook.Close()
    Catch ex As Exception
    End Try
    Try
        xlApp.Quit()
    Catch ex As Exception
    End Try
    Try
        releaseObject(xlApp)
    Catch ex As Exception
    End Try
    Try
        releaseObject(xlWorkBook)
    Catch ex As Exception
    End Try
    Try
        releaseObject(xlWorkSheet)
    Catch ex As Exception
    End Try
End Sub

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
这个解决方案在很多场合对我都有效。我相信诀窍在于调用
ReleaseComObject
函数后,您不会将Excel对象变量设置为
Nothing