Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hosting IE 8 In WinForms and Opening a PDF

We have a form that hosts the WebBrowser control. That is the only control on the form.

We pass the form the file path of a temporary PDF file and it does:

WebBrowser1.Navigate(Me._PathToPdf)

When the form is closing, it navigates away from the PDF file:

WebBrowser1.Hide()
WebBrowser1.Navigate("about:blank")

Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
    Application.DoEvents()
    System.Threading.Thread.Sleep(50)
Loop

Once the form is closed, the calling class then deletes the temporary PDF file.

This process works great... until we installed Internet Explorer 8. For some reason, the combination of IE8 and Adobe Acrobat 8 (or 9) causes an extra file lock handle to be placed on the temporary PDF file. The extra lock handle does not go away until the entire application is shut down. I should also mention that there are no locks on the file until the file is opened by Acrobat.

We can reproduce this on multiple machines and it is always the combination of IE8 and Adobe Acrobat Reader. We can install Foxit Reader 3 instead of Adobe Acrobat and things work fine. Likewise, we can run the app on a machine with IE7 and Adobe Acrobat, and things work fine. But, when you mix the magic potion of IE 8 and Acrobat, you end up with a mess.

Can anyone tell me why I'm getting an extra file lock that persists until the end of the application?

Thanks.

An example application that demonstrates my problem can be found here: PDFLockProblemDemo.zip

like image 944
Jason Williams Avatar asked Apr 30 '09 22:04

Jason Williams


2 Answers

Seems to me the real problems is using a WebBrowser control to host the Adobe Reader web browser plugin to display PDFs. Isn't there a better way to display PDFs directly without introducing a dependency on a web browser? Doesn't Adobe provide an SDK or an ActiveX control you can host directly inside your form?


UPDATE: I looked around and found this post where they access an Adobe ActiveX control (AxAcroPDFLib.AxAcroPDF) and simply call:

axAcroPDF1.LoadFile("mypdf.pdf");
axAcroPDF1.Show();
like image 95
Lucas Avatar answered Sep 19 '22 00:09

Lucas


I have an answer that will not require any temporary files.

I was forced to create a solution, after I was not in the mood of rewriting all my code to use temporary files.

So, here's what you do.

  1. Create a list of strings to hold files to delete
    Dim filesToDelete As List(Of String) = New List(Of String)

  2. You need to set the webbrowser to another pdf file,
    (I created a blank one - black or white; whatever works for you).
    So like webbrowser1.navigate("blank.pdf" )

  3. Add the file to be deleted to a list of strings. so filesToDelete.Add(filename)

  4. Now, here's the trick. The resources will not be released until you get out of this event.
    So you need to do a focus on something else that will cause another event to be fired.
    In my case, I was using a treeview to view the pdf.
    So, after marking the file for deletion using the method above,
    i would set the treeview to a different file.
    So in the TreeView1_BeforeSelect method, I did the obvious:

    If filesToDelete.Count > 0 Then
        For Each f As String In filesToDelete
           File.Delete(f)
        Next
        filesToDelete.Clear()
    End If


    You can adopt your own event, but I'm sure after doing the marking for the delete, you can find something to do that will cause another event to fire. Just follow the flow of your code, what happens next.



So there you have it. Hope this helped someone.

like image 1
user890332 Avatar answered Sep 20 '22 00:09

user890332