4

範囲、シート、およびワークブックを解放するために microsoft.office.interop.excel を使用して Excel を閉じても、Windows でプロセスが閉じられません。

すべての Excel インスタンスを完全に閉じることができますが、ユーザーが別の Excel インスタンスを同時に実行しているかどうかはわかりません。

ここに私が試したすべてがあります

Marshal.ReleaseComObject(myWorksheet)
Marshal.FinalReleaseComObject(myWorksheet)
Marshal.ReleaseComObject(xlRange)
Marshal.FinalReleaseComObject(xlRange)
Marshal.ReleaseComObject(.activeworkbook)
Marshal.FinalReleaseComObject(.activeworkbook)
Marshal.ReleaseComObject(excelApplication)
Marshal.FinalReleaseComObject(excelApplication)
MSExcelControl.QuitExcel()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()

Friend Shared Sub QuitExcel()
    If Not getExcelProcessID = -1 Then
        If Not excelApp Is Nothing Then
            'Close and quit
            With excelApp
                Try
                    Do Until .Workbooks.Count = 0
                        'Close all open documents without saving
                        .Workbooks(1).Close(SaveChanges:=0)
                    Loop
                Catch exExcel As Exception
                    'Do nothing
                End Try
                Try
                    .ActiveWorkbook.Close(SaveChanges:=0)
                Catch ex As Exception
                    'Do nothing
                End Try

                Try
                    .Quit()
                Catch ex As Exception
                    'Do nothing
                Finally
                    myExcelProcessID = -1
                End Try
            End With
            excelApp = Nothing
        End If
    End If
End Sub
4

4 に答える 4

10

良い解決策です。アレックス、これを行う必要はありませんが、実行します。EXCEL は終了しません。私はあなたのソリューションを利用して以下のコードを作成しました。アプリが Excel でインポートまたはエクスポートする前に ExcelProcessInit を呼び出し、完了後に ExcelProcessKill を呼び出します。

Private mExcelProcesses() As Process

Private Sub ExcelProcessInit()
  Try
    'Get all currently running process Ids for Excel applications
    mExcelProcesses = Process.GetProcessesByName("Excel")
  Catch ex As Exception
  End Try
End Sub

Private Sub ExcelProcessKill()
  Dim oProcesses() As Process
  Dim bFound As Boolean

  Try
    'Get all currently running process Ids for Excel applications
    oProcesses = Process.GetProcessesByName("Excel")

    If oProcesses.Length > 0 Then
      For i As Integer = 0 To oProcesses.Length - 1
        bFound = False

        For j As Integer = 0 To mExcelProcesses.Length - 1
          If oProcesses(i).Id = mExcelProcesses(j).Id Then
            bFound = True
            Exit For
          End If
        Next

        If Not bFound Then
          oProcesses(i).Kill()
        End If
      Next
    End If
  Catch ex As Exception
  End Try
End Sub

Private Sub MyFunction()
  ExcelProcessInit()
  ExportExcelData() 'Whatever code you write for this...
  ExcelProcesKill()
End Sub
于 2012-11-23T20:02:08.667 に答える
4

Excelを開いたときにプロセスID(PID)を取得し、後で同じPIDを使用して閉じるという大まかな回避策を見つけました

開く前にすべての Excel プロセスを取得します (別のプロセスが既に実行されている場合):

            msExcelProcesses = Process.GetProcessesByName("Excel")
            'Get all currently running process Ids for Excel applications
            If msExcelProcesses.Length > 0 Then
                For i As Integer = 0 To msExcelProcesses.Length - 1
                    ReDim Preserve processIds(i)
                    processIds(i) = msExcelProcesses(i).Id
                Next
            End If

次に、Excel を開いた直後にプロセスを繰り返します。新しい PIDあなたのものです。

最後に、リストをもう一度繰り返して、ID を持つリストを削除するだけです。

                Dim obj1(1) As Process
                obj1 = Process.GetProcessesByName("EXCEL")
                For Each p As Process In obj1
                    If p.Id = MSExcelControl.getExcelProcessID Then
                        p.Kill()
                    End If
                Next
于 2012-08-02T11:59:42.633 に答える
3

少し前に同じ問題がありました.Marshal.ReleaseComObjectをExcelオブジェクトで使用してみてください。System.Runtime.InteropServices 名前空間にあります。また、事前に Excel オブジェクトを閉じることを忘れないでください。

xlWorkbook.Close();
xlApp.Close();
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlApp);
于 2012-08-01T15:08:20.463 に答える