在 WinForms 中托管 IE 8 并打开 PDF
-
03-07-2019 - |
题
我们有一个承载 WebBrowser 控件的窗体。这是表单上的唯一控件。
我们向表单传递临时 PDF 文件的文件路径,它会执行以下操作:
WebBrowser1.Navigate(Me._PathToPdf)
当表单关闭时,它会离开 PDF 文件:
WebBrowser1.Hide()
WebBrowser1.Navigate("about:blank")
Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
System.Threading.Thread.Sleep(50)
Loop
表单关闭后,调用类就会删除临时 PDF 文件。
这个过程效果很好...直到我们安装了 Internet Explorer 8。由于某种原因,IE8 和 Adobe Acrobat 8(或 9)的组合会导致在临时 PDF 文件上放置额外的文件锁定句柄。在整个应用程序关闭之前,额外的锁句柄不会消失。我还应该提到,在 Acrobat 打开该文件之前,该文件不会被锁定。
我们可以在多台机器上重现它,并且它始终是 IE8 和 Adobe Acrobat Reader 的组合。我们可以安装 Foxit Reader 3 而不是 Adobe Acrobat,一切正常。同样,我们可以在装有 IE7 和 Adobe Acrobat 的计算机上运行该应用程序,并且一切正常。但是,当您将 IE 8 和 Acrobat 的魔药混合在一起时,您最终会陷入混乱。
谁能告诉我为什么我会得到一个额外的文件锁,该锁一直持续到应用程序结束?
谢谢。
可以在此处找到演示我的问题的示例应用程序: PDFLockProblemDemo.zip
解决方案
在我看来真正的问题是使用 WebBrowser
控件托管 Adobe Reader Web 浏览器插件以显示 PDF。是否有更好的方法直接显示 PDF,而不引入对 Web 浏览器的依赖?Adobe 没有提供可直接托管在表单内的 SDK 或 ActiveX 控件吗?
更新:我环顾四周发现 这个帖子 他们访问 Adobe ActiveX 控件的位置(AxAcroPDFLib.AxAcroPDF
)并简单地调用:
axAcroPDF1.LoadFile("mypdf.pdf");
axAcroPDF1.Show();
其他提示
我有一个不需要任何临时文件的答案。
在我没有心情重写所有代码以使用临时文件之后,我被迫创建一个解决方案。
所以,这就是你要做的。
创建一个字符串列表来保存要删除的文件
Dim filesToDelete As List(Of String) = New List(Of String)
您需要将网络浏览器设置为另一个pdf文件,
(我创建了一个空白的 - 黑色或白色;任何对你有用的东西)。
所以喜欢webbrowser1.navigate("blank.pdf" )
将要删除的文件添加到字符串列表中。所以
filesToDelete.Add(filename)
现在,这就是窍门。直到您退出本次活动后,资源才会被释放。
因此,您需要关注其他会导致另一个事件被触发的事情。
就我而言,我使用树视图来查看 pdf。
因此,使用上述方法将文件标记为删除后,
我会将树视图设置为不同的文件。
所以在TreeView1_BeforeSelect
方法,我做了显而易见的事情:
If filesToDelete.Count > 0 Then
For Each f As String In filesToDelete
File.Delete(f)
Next
filesToDelete.Clear()
End If
您可以采用自己的事件,但我确信在完成删除标记后,您可以找到一些可以导致另一个事件触发的事情。只需遵循代码流程,接下来会发生什么。
所以你有它。希望这对某人有帮助。
仍然没有找到解决方案,但更多信息:之前我曾使用 XP Pro、Acrobat *.x 和 .NET 2.0(使用 VS 2005 构建)进行过测试。从那时起,我还在各种场景中进行了测试,包括 Vista、Acrobat 9.x 和 .NET 3.5(使用 VS 2008 构建)。
但结果相同:只要浏览器是IE8,当您在WebBrowser控件上调用Dispose()时,PDF文件就不会被释放。当应用程序关闭时它确实会被释放,但这对我们没有帮助......
希望这可以帮助。
我们在使用 IE8 和 Acrobat 时也遇到了同样的问题。在我们的例子中,我们只需要能够覆盖临时 PDF 并重新显示它。我们发现我们可以简单地打开 PDF,写入 0 个字节,然后关闭。之后我们将打开文件并写入新的 PDF 信息,然后重新显示临时文件。
总之,我们没有解决文件锁定问题,而是只是保留附加的文件句柄并重复使用该文件,直到用户关闭应用程序。
希望这可以帮助。