none
Application Error @ Runtime

    Question

  • Hello,

    I'm working on an application to open pdf files using either the AxAcroPDF or WebBrowser controls.  Preferably I'd like to end up using the WebBrowser control, however, I'm having the same errors using either and I need help in resolving this.

    The following error only occurs at runtime - not in debug mode:

    "The instruction at "0x0546622z" referenced memory at "0x00000014". The memory could not be "read". Click on OK to terminate the program.

    The error only appears if the form containing the AxAcroPDF control is opened.  However, if I run the program and not open the form then click on the button to exit the application, the application exits without errors.  I've tried calling AxAcroPDF.dispose() both on the button.click event and the form.closing event but no help.

    Here's the code I'm using on the form load event:

        Private Sub FormParts_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Cursor = Cursors.WaitCursor
            AxAcroPDF1.LoadFile("C:\EMR\IPCK - T370 (VIN# 319439).pdf")
            AxAcroPDF1.setShowToolbar(True)
            Me.Cursor = Cursors.Default
        End Sub
    


    Here's the code I'm using to Exit the form and return to the main form:

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.Close()
            AxAcroPDF1.Dispose()
            FormMain.Show()
        End Sub
    


    Finally, this is how I'm exiting my application:

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            Me.Close()
        End Sub
    

    I have a suspicion that the pdf isn't being released from memory after it's opened - could this be the case?

    Tuesday, January 24, 2012 6:04 PM

Answers

  • Hello,

    If you are using VS2008 or higher the following demos loading a PDF file into a WebBrowser control where for this example the WebBrowser name is WebBrowser1 but that name can be changed to whatever you want.

    WebBrowser1.Reloader("Your pdf document to load including path")
    

    Place the following code into a code module named PDF_Functions.vb

    Module PDF_Functions
       <Runtime.CompilerServices.Extension()> _
       Public Sub Reloader(ByVal sender As WebBrowser, ByVal FileName As String)
    
          sender.Hide()
          sender.Navigate("about:blank")
    
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
    
          If FileName.Length > 0 Then
             sender.Navigate(FileName)
          End If
    
          sender.Show()
       End Sub
       <Runtime.CompilerServices.Extension()> _
       Public Sub Reloader(ByVal sender As WebBrowser, ByVal FileName As String, ByVal Toggle As Boolean)
    
          If Toggle Then
             sender.Hide()
          End If
    
          sender.Navigate("about:blank")
    
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
    
          If FileName.Length > 0 Then
             sender.Navigate(FileName)
          End If
    
          If Toggle Then
             sender.Show()
          End If
    
       End Sub
       <Runtime.CompilerServices.Extension()> _
       Public Sub CleanUp(ByVal sender As WebBrowser)
    
          sender.Hide()
          sender.Navigate("about:blank")
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
          sender.Dispose()
          System.Threading.Thread.Sleep(100)
       End Sub
       ''' <summary>
       ''' Get total page count in a PDF file
       ''' </summary>
       ''' <param name="FileName"></param>
       ''' <returns></returns>
       ''' <remarks>
       ''' May not work on all PDF files so test prior to implementing in
       ''' your project
       ''' </remarks>
       Public Function GetNoOfPagesPDF(ByVal FileName As String) As Integer
          Dim Result As Integer = 0
          Dim fs As New IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read)
          Dim ReadStream As New IO.StreamReader(fs)
          Dim Contents As String = ReadStream.ReadToEnd()
    
          Dim regx As System.Text.RegularExpressions.Regex = _
             New System.Text.RegularExpressions.Regex("/Type\s*/Page[^s]")
    
          Dim matches As System.Text.RegularExpressions.MatchCollection = regx.Matches(Contents)
          Result = matches.Count
    
          Return Result
    
       End Function
    End Module
    
    

    In the form closing event if you have loaded the WebBrowser1 control with a PDF document then add this code to the closing event

    WebBrowser1.CleanUp()



     

     

     


    KSG
    • Marked as answer by Kismet-Gerald Wednesday, January 25, 2012 10:19 PM
    Tuesday, January 24, 2012 7:11 PM
    Moderator

All replies

  • Is it possible you need to close the document before disposing?  Is there a .Close method on the AxAcroPDF class?

    If that doesn't solve it, have you tried contacting the manufacturer of the control?  It will likely be a little difficult for the forum to help you with a 3rd party control issue.

    Tuesday, January 24, 2012 6:22 PM
  • No Quanta, unfortunately, there isn't.
    Tuesday, January 24, 2012 6:54 PM
  • Hello,

    If you are using VS2008 or higher the following demos loading a PDF file into a WebBrowser control where for this example the WebBrowser name is WebBrowser1 but that name can be changed to whatever you want.

    WebBrowser1.Reloader("Your pdf document to load including path")
    

    Place the following code into a code module named PDF_Functions.vb

    Module PDF_Functions
       <Runtime.CompilerServices.Extension()> _
       Public Sub Reloader(ByVal sender As WebBrowser, ByVal FileName As String)
    
          sender.Hide()
          sender.Navigate("about:blank")
    
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
    
          If FileName.Length > 0 Then
             sender.Navigate(FileName)
          End If
    
          sender.Show()
       End Sub
       <Runtime.CompilerServices.Extension()> _
       Public Sub Reloader(ByVal sender As WebBrowser, ByVal FileName As String, ByVal Toggle As Boolean)
    
          If Toggle Then
             sender.Hide()
          End If
    
          sender.Navigate("about:blank")
    
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
    
          If FileName.Length > 0 Then
             sender.Navigate(FileName)
          End If
    
          If Toggle Then
             sender.Show()
          End If
    
       End Sub
       <Runtime.CompilerServices.Extension()> _
       Public Sub CleanUp(ByVal sender As WebBrowser)
    
          sender.Hide()
          sender.Navigate("about:blank")
          Do Until sender.ReadyState = WebBrowserReadyState.Complete
             Application.DoEvents()
             System.Threading.Thread.Sleep(100)
          Loop
          sender.Dispose()
          System.Threading.Thread.Sleep(100)
       End Sub
       ''' <summary>
       ''' Get total page count in a PDF file
       ''' </summary>
       ''' <param name="FileName"></param>
       ''' <returns></returns>
       ''' <remarks>
       ''' May not work on all PDF files so test prior to implementing in
       ''' your project
       ''' </remarks>
       Public Function GetNoOfPagesPDF(ByVal FileName As String) As Integer
          Dim Result As Integer = 0
          Dim fs As New IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read)
          Dim ReadStream As New IO.StreamReader(fs)
          Dim Contents As String = ReadStream.ReadToEnd()
    
          Dim regx As System.Text.RegularExpressions.Regex = _
             New System.Text.RegularExpressions.Regex("/Type\s*/Page[^s]")
    
          Dim matches As System.Text.RegularExpressions.MatchCollection = regx.Matches(Contents)
          Result = matches.Count
    
          Return Result
    
       End Function
    End Module
    
    

    In the form closing event if you have loaded the WebBrowser1 control with a PDF document then add this code to the closing event

    WebBrowser1.CleanUp()



     

     

     


    KSG
    • Marked as answer by Kismet-Gerald Wednesday, January 25, 2012 10:19 PM
    Tuesday, January 24, 2012 7:11 PM
    Moderator
  • Not familiar with that library but is there a AxAcroPDF1.Close() method?

    .Dispose will try to dispose of the object but the document may still be open in memory.


    Try to look ahead so you're not forced to look behind.
    Tuesday, January 24, 2012 7:21 PM
  • Kevin,

    Would I call this module from the form.load event?

    Tuesday, January 24, 2012 7:43 PM
  • Kevin,

    Would I call this module from the form.load event?


    Hello,

    You can call this from form load or a place such as a button click event you care too.


    KSG
    Tuesday, January 24, 2012 11:09 PM
    Moderator
  • Kevin,

    Would I call this module from the form.load event?


    Had a few minutes to slap a sample project together found here. Also included is a fun language extension shown below which in short displays a simple page with "Welcome" displayed centered in the WebBrowser canvas.

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <remarks>
    ''' Just for fun but could easily be a company standard welcome screen
    ''' or a disclaimer screen etc.
    ''' </remarks>
    <Runtime.CompilerServices.Extension()> _
    Public Sub WelcomeMessage(ByVal sender As WebBrowser)
        sender.DocumentText = _
        <html>
            <head>
                <style type="text/css" media="screen">
                body {color: black;background-color: white;margin: 0px}
                #horizon {color: black;	background-color: white;text-align: center;	position: absolute;	top: 50%;left: 0px;	width: 100%;height: 1px;overflow: visible;visibility: visible;display: block}
                #content {font-family: Verdana, Geneva, Arial, sans-serif;background-color: white;margin-left: -125px;	position: absolute;top: -35px;left: 50%;width: 250px;height: 20px;	visibility: visible}
                .bodytext {font-size: 14px}
                .headline {font-weight: bold;font-size: 24px}
                </style>
            </head>
            <body>
                <div id="horizon">
                    <div id="content">
                        <div class="bodytext">
                            <span class="headline">Welcome</span>
                        </div>
                    </div>
                </div>
    
            </body>
        </html>.ToString
    
        Do Until sender.ReadyState = WebBrowserReadyState.Complete
            Application.DoEvents()
            System.Threading.Thread.Sleep(100)
        Loop
    End Sub

     


    KSG
    Wednesday, January 25, 2012 12:01 AM
    Moderator
  • Wow Kevin,

    Thank you so much.  I'm reading through the code to ensure that I understand how it works before implementing it.  I'm very new to programming, but I'm learning fast - thanks to people like you.

    Anyway, so while going through the code I realized that your button (cmdOpen) click functions fires up a filedialog box where the user can select which file to open.  In my application, I don't want to user to be able to select the file.  I want the WebBrowser control to load the file when the button is clicked.

    So do you think I could just do the following?

    WebBrowser1.Navigate("File Path")
    

    Thanks again for your assistance Kevin, really appreciate it.

    Wednesday, January 25, 2012 4:50 PM
  • If you use a method like dispose, than don't direct assume that it is the same as in most windows forms controls a method which implements IDisposable.

    It can be any method name the programmer wanted to use, Dispose comes from the french word "disponer" which means "place at", however has many meanings in the many dialects English has. For the same the programmer could have given it the name Kismet. Dispose is not a keyword.

    So read carefully the specification around that method before you start assuming it is the same as implementing IDisposable which removed unmanaged resources from an object and makes that object which calls it  becomes unusable (be aware it does not release the object in that implementation)


    Success
    Cor
    Wednesday, January 25, 2012 5:09 PM
  • Guys (especially Kevin),

    Thanks for all your assistance.  Using the code and example project provided by Kevin I was able to solve my issue.

    The memory error was still occuring, but I managed to solve it by calling the .Cleanup() method of WebBrowser1 on the FormClosing event of the main form itself.  So that the browsers contents are cleaned up when the application is exiting.

    It worked and the error is no longer being displayed.  Problem solved.

    Thanks again.

    Wednesday, January 25, 2012 10:23 PM
  • Wow Kevin,

    Thank you so much.  I'm reading through the code to ensure that I understand how it works before implementing it.  I'm very new to programming, but I'm learning fast - thanks to people like you.

    Anyway, so while going through the code I realized that your button (cmdOpen) click functions fires up a filedialog box where the user can select which file to open.  In my application, I don't want to user to be able to select the file.  I want the WebBrowser control to load the file when the button is clicked.

    So do you think I could just do the following?

     

    WebBrowser1.Navigate("File Path")
    

    Thanks again for your assistance Kevin, really appreciate it.

     


    Yes that is correct but I would suggest before Navigating to a hard coded file to first check if the file exists using IO.File.Exist function.
    KSG
    Wednesday, January 25, 2012 10:52 PM
    Moderator
  • Yes that is correct but I would suggest before Navigating to a hard coded file to first check if the file exists using IO.File.Exist function.

    Thanks Kevin,

    Since I don't want to use the file dialog box at all, what would be the purpose of checking to see if the file exists? 

    I mean, the file will always exist and I want the browser to navigate to it when the corresponding button is pressed by the user.  To this end I think I am not using the module you created, because it would open the file dialog box - which isn't what I want - but haven't figured out how to modify the code yet (I'm still studying it and researching, thus learning to do it).

    But do feel free to offer up a modification if that's okay with you.

    Thanks again.

     

    //Kismet

    Thursday, January 26, 2012 12:50 PM