VB.NET System.AccessViolationException: Attempted to read or write protected memory.

Hey guys... This has had me stumped all day so I figured I'd get some expert advise. I have a program that is doing some basic form screen scraping using API calls. Once I start reading in the various text elements on the child form, after about 10 iterations I get the following error:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  at CaptureTextTest.Form1.EnumChildWindows(Int32 hWndParent, EnumChildWindProc lpEnumFunc, Int64 lParam)
  at CaptureTextTest.Form1.Button3_Click(Object sender, EventArgs e) in C:\... Form1.vb: line 140

I read that there was a hot fix for this issue: http://support.microsoft.com/?kbid=923028 but it does not seem applicable as I'm running .Net 3.5 SP1 on the machine in question. I've attached the code in full.

Option Strict Off
Option Explicit On
Imports System.Windows.Forms.Application
Imports System.Threading.Thread
Imports System.Runtime.InteropServices
Public Class Form1
    Public hWnd As Long
    Public obj As New TCaptureXLib.TextCaptureX
    Public strResults As String
    Public strWinTitle As String
    Public lhWndP As Long
    Public strCaption As String
    Public blnCustomScrape As Boolean
    Private strMyScrape As String


    <DllImport("user32", EntryPoint:="GetWindowTextLength")> _
Private Shared Function GetWindowTextLength( _
ByVal hwnd As Int32) As Int32
    End Function
    <DllImport("user32", EntryPoint:="FindWindow")> _
    Private Shared Function FindWindow( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Int32
    End Function
    <DllImport("user32", EntryPoint:="GetWindowText")> _
    Private Shared Function GetWindowText( _
    ByVal hwnd As Int32, _
    ByVal lpString As System.Text.StringBuilder, _
    ByVal cch As Int32) As Int32
    End Function
    <DllImport("user32", EntryPoint:="GetWindow")> _
    Private Shared Function GetWindow( _
    ByVal hwnd As Int32, _
    ByVal wCmd As Int32) As Int32
    End Function
    Private Const GW_HWNDNEXT As Int32 = 2
    Private Declare Function BringWindowToTop Lib "user32" (ByVal _
         hwnd As Long) As Long
    Private Const WM_GETTEXT As Integer = &HD
    Private Const WM_GETTEXTLENGTH As Integer = &HE

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
            (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, _
            ByVal lpsz2 As String) As Integer

    Private Declare Function SendMessage2 Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer

    Delegate Function EnumChildWindProc(ByVal hWnd As Int32, ByVal lParam As Long) As Boolean
    Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Int32, ByVal lpEnumFunc As EnumChildWindProc, ByVal lParam As Long) As Long


    Private Sub CaptureWindow(ByVal hWnd)
        strResults = ""
        Do Until Not strResults = ""
            strResults = obj.CaptureActiveWindow()
            If strResults <> "" Then
                RichTextBox1.Text = strResults
            End If
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    End Sub
    Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
        GetHandleFromPartialCaption = False
        'Get the parent window using API
        lhWndP = FindWindow(vbNullString, vbNullString)
        'Get the child window here
        If lhWndP <> 0 Then

        End If
        Do While lhWndP <> 0
            Dim iStr As Integer = GetWindowTextLength(lhWndP) + 1
            Dim sStr As New System.Text.StringBuilder(iStr)
            GetWindowText(lhWndP, sStr, iStr)
            strCaption = sStr.ToString
            If InStr(1, strCaption, sCaption) > 0 Then
                GetHandleFromPartialCaption = True
                lWnd = lhWndP
                Exit Do
            End If
            lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    End Function
    Private Sub QuickRefresh(ByVal i As Integer)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    End Sub
    Private Sub GetHandle()
        If GetHandleFromPartialCaption(lhWndP, "Practice Plus") = True Then
            'MsgBox("Found Window Handle: " & lhWndP, vbOKOnly + vbInformation)
            If blnCustomScrape = False Then
            End If
            MsgBox("Window 'Horizon' was not found", vbOKOnly + vbExclamation)
        End If
    End Sub

    Private Function GetWindowText(ByVal hWnd As IntPtr) As String
        Dim textLength As Integer = SendMessage2(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1
        Dim sb As New System.Text.StringBuilder(textLength)
        If textLength > 0 Then
            Call SendMessage(hWnd, WM_GETTEXT, textLength, sb)
        End If
        Return sb.ToString
    End Function

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        blnCustomScrape = True

            Dim proc As New EnumChildWindProc(AddressOf EnumChildWindow)
            Call EnumChildWindows(lhWndP, proc, 0&) 'This is the call that generates error

        Catch ex As Exception
            ex = ex
        End Try
    End Sub
    Function EnumChildWindow(ByVal hChild As Int32, ByVal lParam As Long) As Boolean

        Dim wText As New System.Text.StringBuilder(255)
        Dim j As Long
        j = GetWindowText(hChild, wText, 255)
        j = j
        'I get about 10 text elements from 
		'the child form before the error takes place
        strMyScrape = strMyScrape + wText.ToString
        EnumChildWindow = 1  ' Continue enumeration       
    End Function

End Class

Open in new window

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
You've got a mish-mash of Long/Int32/Integer which means you probably copied or partially converted some old VB6 code.

Change all the occurrences of "Long" to "Integer" (or IntPtr if appropriate) and the error will probably go away...

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
romiebehuninAuthor Commented:
Yeah your right I added some delegates etc to convert some old VB6 stuff into this project... good suggestion I'll get to work on that shortly and then let you know if that solved the problem.
romiebehuninAuthor Commented:
Excellent suggestion... did the trick!! Thank You!!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.