Brad Smith の実装を使用して、Winforms/VB.Net に PreviewHandler コントロールを実装しました。
ただし、コントロールが破棄され、最後にプレビューされたファイルが Excel ファイルである場合は常に、IPreviewHandler.Unload() を呼び出すと、RPC_E_SERVERFAULT でキャッチできない ComException が発生し、アイドル状態の Excel32.exe プロセスが発生します (その上で、私のプロセスを手動で停止するまで、別の Excel ファイルをプレビューしようとするとアプリ)。
Brad の記事のコメントで回避策を見つけました。これは、所有者フォームの FormClosing イベントにフックし、そこからプレビュー ハンドラーをアンロードすることです。ただし、コメントでは、作成者は、コントロールではなく、フォームを含むコードのイベントにフックします。
コントロール内の FormClosing イベントにフックする唯一の方法は、ParentChanged イベントにフックし、フォームが見つかるまで一番上の親に移動し、そこから FormClosing ハンドラーを追加することです。
ただし、これはすべての場合に機能するとは限りません (たとえば、私の PreviewHandler コントロールは、フォームの前に作成された別のコントロール内にネストされています)。
それで、その厄介なCOMExceptionを取得せずにプレビューハンドラーコントロールを適切に破棄する方法、またはコントロール内から親フォームを見つける方法はありますか?
Dispose コードは次のとおりです。
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
UnloadPreviewHandler()
Catch
End Try
GC.Collect()
MyBase.Dispose(disposing)
End Sub
Private Sub UnloadPreviewHandler()
If previewHandler IsNot Nothing Then
Try
' This line throws the exception when UnloadPreviewHandler is called from Dispose method.
previewHandler.Unload()
Finally
Marshal.FinalReleaseComObject(previewHandler)
previewHandler = Nothing
End Try
End If
If previewStream IsNot Nothing Then
previewStream.Close()
previewStream = Nothing
End If
If Not String.IsNullOrWhiteSpace(currentTempFile) Then
Try
IO.File.Delete(currentTempFile)
Catch
End Try
End If
End Sub
編集: コメントが示唆したように、C4F 実装を試しました (キットをダウンロードし、PreviewHandlerHost サンプルを実行しました)。この問題は、それらの実装でも発生します (Excel または Word ファイルのプレビュー中にアプリを閉じます)。