我使用 Brad Smith 的实现在 Winforms/VB.Net 中实现了 PreviewHandler 控件。
但是,每当我的控件释放并且最后一个预览文件是 Excel 文件时,在调用 IPreviewHandler.Unload() 时,我会收到一个带有 RPC_E_SERVERFAULT 的无法捕获的 ComException,并且我最终会得到一个空闲的 Excel32.exe 进程(最重要的是,它会挂起我的应用程序,当我尝试预览另一个 Excel 文件,直到我手动停止该过程)。
我在 Brad 的文章的评论中找到了一种解决方法,即挂钩到所有者表单的 FormClosing 事件,并从那里卸载预览处理程序。但是,在注释中,作者在包含表单的代码中挂钩到事件,而不是在控件中。
我发现挂钩到控件中的 FormClosing 事件的唯一方法是挂钩到 ParentChanged 事件,并向上导航到顶部父级,直到找到一个表单,然后从那里添加 FormClosing 处理程序。
但是,这并不适用于所有情况(例如,我的 PreviewHandler 控件嵌套在另一个在窗体之前创建的控件中)。
那么有什么方法可以正确处理我的预览处理程序控件而不会得到那个讨厌的 COMException,或者有什么方法可以从控件中找到父窗体?
处置代码如下:
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 文件时关闭应用程序)。