Best Way to Release Excel Interop com Object

前端 未结 5 817
不知归路
不知归路 2020-12-11 12:48

Experts, Please let me know the best way I can do this...

I am working on a VB.Net application that uses the Microsoft.Office.Interop.Excel Object Library to create

5条回答
  •  盖世英雄少女心
    2020-12-11 13:12

    I share VB.net code:

    Imports System.Runtime.InteropServices
    Namespace Jobs
    
    Public Class Job
        Implements IDisposable
    
        ', 
        CallingConvention:=CallingConvention.Cdecl)>
        Shared Function CreateJobObject(a As IntPtr, lpName As String) As IntPtr
        End Function
    
        
        Public Shared Function SetInformationJobObject(hJob As IntPtr, infoType As 
        JobObjectInfoType, lpJobObjectInfo As IntPtr, cbJobObjectInfoLength As UInteger) As Boolean
        End Function
    
        
        Public Shared Function CloseHandle(Token As IntPtr) As Boolean
        End Function
    
        
        Public Shared Function AssignProcessToJobObject(job As IntPtr, process As IntPtr) as Boolean
        End Function
    
        Private m_handle As IntPtr
        Private m_disposed As Boolean = False
    
        Public Sub New()
    
            m_handle = CreateJobObject(IntPtr.Zero, Nothing)
    
            Dim info As JOBOBJECT_BASIC_LIMIT_INFORMATION = New JOBOBJECT_BASIC_LIMIT_INFORMATION()
            info.LimitFlags = &H2000
    
            Dim extendedInfo = New JOBOBJECT_EXTENDED_LIMIT_INFORMATION()
            extendedInfo.BasicLimitInformation = info
    
            Dim length As Integer = Marshal.SizeOf(GetType(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))
            Dim extendedInfoPtr As IntPtr = Marshal.AllocHGlobal(length)
            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, False)
    
            If (Not SetInformationJobObject(m_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, length)) Then
                Throw New Exception(String.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()))
            End If
        End Sub
    
    #Region "IDisposableMembers"
    
        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    
    #End Region
        Private Sub Dispose(disposing As Boolean)
            If m_disposed Then
                Return
            End If
            If disposing Then
            End If
            Close()
            m_disposed = True
        End Sub
    
        Public Sub Close()
            CloseHandle(m_handle)
            m_handle = IntPtr.Zero
        End Sub
    
        Public Function AddProcess(handle As IntPtr) As Boolean
            Return AssignProcessToJobObject(m_handle, handle)
        End Function
    
    End Class
    
    Public Enum JobObjectInfoType
        AssociateCompletionPortInformation = 7
        BasicLimitInformation = 2
        BasicUIRestrictions = 4
        EndOfJobTimeInformation = 6
        ExtendedLimitInformation = 9
        SecurityLimitInformation = 5
        GroupInformation = 11
    End Enum
    
    
    Public Structure SECURITY_ATTRIBUTES
        Public nLength As Integer
        Public lpSecurityDescriptor As IntPtr
        Public bInheritHandle As Integer
    End Structure
    
    
    Structure JOBOBJECT_BASIC_LIMIT_INFORMATION
        Public PerProcessUserTimeLimit As Int64
        Public PerJobUserTimeLimit As Int64
        Public LimitFlags As Int16
        Public MinimumWorkingSetSize As UInt32
        Public MaximumWorkingSetSize As UInt32
        Public ActiveProcessLimit As Int16
        Public Affinity As Int64
        Public PriorityClass As Int16
        Public SchedulingClass As Int16
    End Structure
    
    
    Structure IO_COUNTERS
        Public ReadOperationCount As UInt64
        Public WriteOperationCount As UInt64
        Public OtherOperationCount As UInt64
        Public ReadTransferCount As UInt64
        Public WriteTransferCount As UInt64
        Public OtherTransferCount As UInt64
    End Structure
    
    
    Structure JOBOBJECT_EXTENDED_LIMIT_INFORMATION
        Public BasicLimitInformation As JOBOBJECT_BASIC_LIMIT_INFORMATION
        Public IoInfo As IO_COUNTERS
        Public ProcessMemoryLimit As UInt32
        Public JobMemoryLimit As UInt32
        Public PeakProcessMemoryUsed As UInt32
        Public PeakJobMemoryUsed As UInt32
    End Structure
    
    End Namespace
    

    And, in the class where you plan to implement:

    
    Public Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As UInteger) As UInteger
    End Function
    
    
    'Implements
    Dim oExcelApp = New Microsoft.Office.Interop.Excel.Application
    Dim job As Jobs.Job = New Jobs.Job()
    Dim pid As UInteger = 0
    GetWindowThreadProcessId(New IntPtr(oExcelApp.Hwnd), pid)
    job.AddProcess(Process.GetProcessById(pid).Handle)
    
    oExcelApp.Workbooks.Open(RutaArchivoExcel)
    
    'Code work code here
    
    oExcelApp.Workbooks(1).Close()
    oExcelApp.Quit()
    
    'Then Dispose correctly the excel app and windows distroy appropiately the process
    job.Dispose()
    

    i test this with Microsoft Excel 2016.

提交回复
热议问题