タスクマネージャにExcelプロセスが残ってしまう

解決


まさお  2013-06-12 16:18:56  No: 148167  IP: 192.*.*.*

まさお と申します。  宜しくお願い致します。

    WinXP Pro SP3,VB2010 Express SP1
    .NET Framework 4
    MS-Office Excel2003 SP3,Word2003 SP3
  です。

  下記コードであるファイルを開くと次のエラーになりタスクマネージャに Excelプロセスが残ってしまいます。
      ※エラー発生ファイル詳細は最後尾に記しました。
  【エラー内容】
    System.Runtime.InteropServices.COMException
    サーバーによって例外が返されました。 (HRESULT からの例外: 0x80010105 (RPC_E_SERVERFAULT))

  エラーが発生するのは良いのですがExcelプロセスが残ってしまうので困っています。
  Excelプロセスが残らないようにする対処方法を教えて戴きたくお願い致します。

***** 以下コード *****
'参照設定:Microsoft Excel 11.0 Object Library
Imports XLS = Microsoft.Office.Interop.Excel

Public Class ClassMyExcel
        Private XL As XLS.Application
        Private WBs As XLS.Workbooks
        Private WB As XLS.Workbook

    Public Sub foo()
        Dim WBFullPath As String = "c:\hoge.mht" 'Wordで作成した.mhtファイル
        Try
            XL = New XLS.Application
            WBs = XL.Workbooks
            WB = WBs.Open(Filename:=WBFullPath)
            WB.Close(SaveChanges:=False)
            Me.MRComObject(WB)

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        Finally
            If Not IsNothing(WB) Then WB.Close(SaveChanges:=False)
            Me.MRComObject(WB)
            Me.MRComObject(WBs)
            XL.Quit()
            Me.MRComObject(XL)

        End Try

         MessageBox.Show("Complete")
    End Sub

    Private Sub MRComObject(Of T As Class)(ByRef objCom As T)
        'http://www.hanatyan.sakura.ne.jp/patio/read.cgi?no=319 を参考にしました。
        If objCom Is Nothing Then Return
        Try
            If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then
                Dim count As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
                                                                            '.FinalReleaseComObject(でも同じ)
                If count <> 0 Then
                    Try
                        MessageBox.Show(TypeName(objCom) & " 要調査! デクリメントされていません。")
                    Catch ex As Exception
                        MessageBox.Show("Catch発生 要調査! デクリメントされていません。")
                    End Try
                End If
            Else
                MessageBox.Show("ComObject ではありませんので、解放処理の必要はありません。")
            End If
        Finally
            objCom = Nothing
        End Try
    End Sub
End Class
***** 以上コード *****


≪エラー発生ファイル詳細≫
  MS-Office Wordから以下のようにして作成しました。
  単純な.mhtファイルではエラーは発生しませんが、私の環境では以下でエラー発生ファイルを作成できます。
  1)メニュー:ファイル → 新規作成 → 「新しい文書」ダイアログ「Webページ」選択。
  2)メニュー:挿入 → テキストボックス → 横書き → 
    【描画をここに作成します】の枠外にテキストボックスを作成。
  3)上記2)で作成したテキストボックスに『1<tab>』と入力。
    <tab>はTabキー入力(Microsoft.VisualBasic.ControlChars.Tab)です。
  4)上記2),3)を繰り返し。
    つまり『文字 & <tab>』のテキストボックスを2つ作ります。
  5)ファイルの種類「単一ファイル Webページ(*.mht; *.mhtml)」で保存。

  a)上記2)で【描画をここに…】枠内にテキストボックスを作成するとエラー発生しません。
  b)テキストボックス一つではエラー発生しません。
  c)文字だけ(<tab>無し)ではエラー発生しません。
  d)<tab>だけ(文字無し)ではエラー発生しません。
  e)一方のテキストボックスが『文字 & <tab>』、もう一方が『<tab>』でエラー発生します。

  『何故Wordで作成したWeb用ファイルをExcelで開くのか?』の説明は割愛させてください。
  全ての.mhtファイルでエラーになるなら拡張子で判別するのですが、エラーにならない.mhtファイルもあるので
可能ならばExcelで開きたいと考えております。


以上、宜しくお願い致します。

編集 削除
shu  2013-06-20 12:24:49  No: 148168  IP: 192.*.*.*

あやしいのは
 If Not IsNothing(WB) Then WB.Close(SaveChanges:=False)
がFinally句で実行されていること。
Closeで例外が発生しているとするとFinallyで実行しても
例外が発生するので以降の処理が行われていないのでは?

編集 削除
まさお  2013-06-20 17:17:38  No: 148169  IP: 192.*.*.*

shu さん、ありがとうございます。

  説明の為ソースを少し変更しました。 下記を参照願います。


  説明不足で申し訳ありませんでした。
> 【エラー内容】System.Runtime.InteropServices.COMException
は、下記ソース※Aで発生します。
  ですので、WBは Nothing のままです。
  よって Finally句での※Bでは False と判定されて※Cは実行されません。

  是非とも引き続きアドバイスをお願い致します。



  と、ここまで書いて「逆に※Dを実行した際、Sub MRComObject で※EによりExcelプロセスが残ってしまうのではないか」と
思いました。
  ※Aでエラーになる為 WB は Nothing のままだが、Excelプロセスはセットされている、ということはありますでしょうか?
        ※EをREM文にすると※Fで「System.ArgumentNullException」が発生しますので外せません。
  もし、そうならどうすれば良いでしょうか?


    Public Sub foo()
        Dim WBFullPath As String = "c:\hoge.mht" 'Wordで作成した.mhtファイル
        Try
            XL = New XLS.Application
            WBs = XL.Workbooks
            WB = WBs.Open(Filename:=WBFullPath) '※A
            WB.Close(SaveChanges:=False)
            Me.MRComObject(WB)

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        Finally
            Try
                If Not IsNothing(WB) Then '※B
                    WB.Close(SaveChanges:=False) '※C
                End If
            Catch ex As Exception
                '念の為の Catchブロック 
            End Try

            Me.MRComObject(WB)'※D
            Me.MRComObject(WBs)
            XL.Quit()
            Me.MRComObject(XL)

        End Try

         MessageBox.Show("Complete")
    End Sub

    Private Sub MRComObject(Of T As Class)(ByRef objCom As T)
        'http://www.hanatyan.sakura.ne.jp/patio/read.cgi?no=319 を参考にしました。
        If objCom Is Nothing Then Return '※E
        Try
            If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then '※F
                Dim count As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom)
                                                                            '.FinalReleaseComObject(でも同じ)
                If count <> 0 Then
                    Try
                        MessageBox.Show(TypeName(objCom) & " 要調査! デクリメントされていません。")
                    Catch ex As Exception
                        MessageBox.Show("Catch発生 要調査! デクリメントされていません。")
                    End Try
                End If
            Else
                MessageBox.Show("ComObject ではありませんので、解放処理の必要はありません。")
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        Finally
            objCom = Nothing
        End Try
    End Sub

編集 削除
まさお  2013-06-20 17:26:33  No: 148170  IP: 192.*.*.*

自己レスです。

>   ※Aでエラーになる為 WB は Nothing のままだが、Excelプロセスはセットされている

  違うかもしれません。
  ※Aで未存在ファイルを指定すると「System.Runtime.InteropServices.COMException」エラーが発生します。
  WB は Nothing のままなのでで※Eで Return しますが、タスクマネージャに Excel プロセスが残ることはありませんでした。

編集 削除
まさお  2013-07-16 15:34:37  No: 148171  IP: 192.*.*.*

自己レスです。

解決はしておりませんが、これ以上のアドバイスを戴けなさそうなので≪解決≫にします。

  shu さん、ご検討くださった先輩諸兄、ありがとうございました。

編集 削除