C# 在WinForms中托管IE 8并打开PDF

C# 在WinForms中托管IE 8并打开PDF,c#,vb.net,file,internet-explorer-8,acrobat,C#,Vb.net,File,Internet Explorer 8,Acrobat,我们有一个承载WebBrowser控件的窗体。这是窗体上唯一的控件 我们向表单传递临时PDF文件的文件路径,它执行以下操作: WebBrowser1.Navigate(Me._PathToPdf) 关闭表单时,它将从PDF文件中导航出去: WebBrowser1.Hide() WebBrowser1.Navigate("about:blank") Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete Appli

我们有一个承载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文件

这个过程非常有效。。。直到我们安装了InternetExplorer8。出于某种原因,IE8和Adobe Acrobat 8(或9)的组合会在临时PDF文件上放置一个额外的文件锁定句柄。在整个应用程序关闭之前,额外的锁句柄不会消失。我还应该提到,在Acrobat打开文件之前,文件上没有锁

我们可以在多台机器上复制,它总是IE8和AdobeAcrobatReader的组合。我们可以安装FoxitReader3而不是AdobeAcrobat,一切正常。同样,我们可以在一台装有IE7和AdobeAcrobat的机器上运行该应用程序,一切正常。但是,当你把IE 8和Acrobat的神奇药水混合在一起时,你会陷入一片混乱

有人能告诉我为什么我会得到一个额外的文件锁,它会一直持续到应用程序结束吗

谢谢


可以在此处找到演示我的问题的示例应用程序:

仍然没有找到解决方案,但更多信息: 之前我用XP Pro、Acrobat*.x和.NET 2.0(用VS2005构建)进行了测试。从那时起,我还测试了各种场景,包括Vista、Acrobat9.x和.NET3.5(使用VS2008构建)

但结果是一样的:只要浏览器是IE8,在WebBrowser控件上调用Dispose()时,PDF文件就不会被释放。它会在应用程序关闭时发布,但这对我们没有帮助


希望这能有所帮助。

我们在IE8和Acrobat上也遇到了同样的问题。在我们的例子中,我们只需要能够覆盖临时PDF并重新显示它。我们发现,我们可以简单地打开PDF,写入0字节,然后关闭。之后,我们将打开文件并写入新的PDF信息,然后重新显示临时文件

总之,我们没有解决文件锁定问题,而是将文件句柄附加在一起,并在用户关闭应用程序之前重新使用该文件


希望这能有所帮助。

在我看来,真正的问题在于使用
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)

  • 您需要将webbrowser设置为另一个pdf文件,
    (我创建了一个空白文件-黑色或白色;任何适合您的文件)
    就像
    webbrowser1.导航(“blank.pdf”)

  • 将要删除的文件添加到字符串列表中。所以
    filesToDelete.Add(文件名)

  • 现在,诀窍来了。在您退出此事件之前,不会释放资源
    因此,您需要将注意力集中在其他会导致触发另一事件的事件上
    在我的例子中,我使用树视图查看pdf。
    因此,在使用上述方法将文件标记为删除后,
    我会将树视图设置为其他文件
    所以在
    TreeView1\u BeforeSelect
    方法中,我做了一个显而易见的:

    如果filesToDelete.Count>0,则

    用于filesToDelete中的每个f As字符串
    
    文件。删除(f)

    下一步

    filesToDelete.Clear()

    如果结束



    您可以采用您自己的事件,但我相信在完成删除标记后,您可以找到一些可以导致另一个事件触发的操作。只需遵循代码流程,接下来会发生什么




  • 你就这样了。希望这对某人有所帮助。

    是的,这也准确地描述了我们遇到的情况。感谢您的更新。是的,我们实际上使用了Adobe Acrobat提供的COM对象。然而,这并不理想,因为现在我们直接与AdobeAcrobat绑定,并且必须将该程序作为应用程序的先决条件。以前,我们只需要一个PDF查看应用程序(大多数情况下是Acrobat或Foxit)。好吧,我们找不到解决这个问题的好方法,所以我们在表单上使用ActiveX Acrobat Reader控件。不幸的是,这将我们与Acrobat Reader的一个版本联系在了一起,但有必要将这个版本发布出去。我要结束这个问题。您可以调用
    Application.DoEvents()
    ,然后执行删除操作,而不是触发事件。