Reading stdout from VB6


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 7 of 7

Thread: Reading stdout from VB6

Hybrid View

  1. #1
    Join Date
    Mar 2005
    Posts
    3

    Reading stdout from VB6

    Let me first say i'm a VB6 newbie, so please be kind

    I am trying to write a console (dosbox) app monitoring program in VB6 where i can pipe the stdout to my VB app, but i'm having a few problems. I have found several pieces of example code for piping output from console apps, but they all seem to be aimed at firing the app, grabbing a small amount of info from stdout and then closing.

    What i need to do is fire up 3 console processes and then periodically check the processes are still running (restarting them if they are not) and grab the stdout from each to place in my output panels in my VB form. All 3 console apps are persistent and are expected to output quite a lot in a short amount of time.

    I am starting with just one of the console apps to simplify things until i get it somewhere close to working. I can get the console app started and i'm trying to use a timer to call the stdout grabbing, it works for a few seconds then the VB form freezes until i kill the console. Once the console is gone the VB form unfreezes and dumps the rest of the output where i want it, it does always seem to freeze at about the same spot in the output though even if i change the read buffer size. I have tried different lengths between timer calls (1 second up to 30), and the number of times the timer code is successfully called before lockup varies depending on the timer length.

    I've played with several examples now and seem to get the same results from each method i've tried.

    Here's the current code i'm playing with (pulled from here somewhere i think)....
    Private Sub Form_Load()


    With sa
    .nLength = Len(sa)
    .bInheritHandle = 1 ' get inheritable pipe handles
    End With 'SA

    ret = CreatePipe(hPipeRead, hPipeWrite, sa, 0)

    With si
    .cb = Len(si)
    .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
    .wShowWindow = 1 'SW_HIDE ' hide the window
    .hStdOutput = hPipeWrite
    .hStdError = hPipeWrite
    End With 'SI

    If CreateProcess(vbNullString, "c:\test\testapp1.exe", ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&, "c:\test\", si, pi) Then
    Call CloseHandle(hPipeWrite)
    Call CloseHandle(pi.hThread)
    hPipeWrite = 0
    Timer1.Enabled = True
    ' Call CloseHandle(pi.hProcess)
    End If

    Private Sub Timer1_Timer()
    Do
    DoEvents
    If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then
    Exit Do
    End If
    sOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
    Text1.SelText = Text1.SelText + sOutput
    Loop
    End Sub
    Any help would be greatly appreciated as i'm just stuck now!

  2. #2
    Join Date
    Feb 2004
    Location
    Colton, CA
    Posts
    550
    Do you understand each line of code that you've pulled in from elsewhere?

    I'd start by looking at each method and function on msdn.microsoft.com and get a better understanding of what the code is actually doing.

    I'm not trying to be un-helpful, but if someone suggests a solution which you implement, you still won't understand how or why the app. now works.

    I know us newbies need all the help we can get, but you need to help yourself also.

    Happy searching.

  3. #3
    Join Date
    Mar 2005
    Posts
    3
    I do actually understand the code quite well, i'm fluent in VBScript and have done a lot of work in numerous other languages including about a dozen BASIC variations (ok, that's going back a bit), several scripting languages, assembler (also going back a bit) and a small amount of C++/Delphi. I currently work a lot with PHP, but i'm learning VB as i code a lot of tools/utils as i need them and VB is pretty simple for this purpose.

    I start most coding projects by looking at snippets of how other people tackle the things i want to achieve in case there is a way i've not thought of or a more efficient method than mine, i've always found it a good way to learn new techniques. In this case i've stripped out all of my own stuff and reverted to just the example code to try and pin down the problem.

    The thing i don't understand is why the output stops at the same point each time, then continues after i exit the console app. The timer function is called successfully, the amount of times depends on the frequency and size of data i read from the pipe so it's not sticking on the n'th time it's called. There is a Doevents in the do loop to keep the app polling whilst the pipe is read and and i'm not losing the pipe handle or the output wouldn't continue another dozen lines after killing the console app when reading a byte a second from the pipe. For the same reason it can't be the text limit on the text box in the form either as it gets about a dozen lines before freezing, then about another dozen afterwards. It can't be attempting to read past the last bytes in the pipe if i'm reading a byte a time and have the exit do check.

    As i mentioned all of the code examples i have seen launch the console app, read the stdout and then close everything in the same sub/funtion. The only real differences between that code and what i am doing is i am passing the handle to another sub, but as the output does come back then it must be being passed correctly.

  4. #4
    Join Date
    Feb 2004
    Location
    Colton, CA
    Posts
    550
    Sorry. When you said you were a newbie, I assumed you meant you are new to programming, and that you had just copied the code from somewhere.

  5. #5
    Join Date
    Mar 2005
    Posts
    3
    No problem. As i am a VB6 newbie, and i technically *did* copy that portion of the code it was a correct response

  6. #6
    Join Date
    Jan 2004
    Location
    Alexandria, VA
    Posts
    392
    Have you tried running the program in the IDE and stepping through it in debug mode to see what line it is freezing (or looping infinitely) on?
    Bob Rouse
    Dimension Data

  7. #7
    Join Date
    Nov 2003
    Location
    Alameda, CA
    Posts
    1,737
    The problem here is that you are using a timer, and then you put a loop inside it. Because you did not stop the timer, you get a re-entrance in the same sub at the next DoEvents (yes, I still hate DoEvents). Probably you can solve this problem disabling the timer as the first line of the timer event, but I'd prefer:

    Code:
    Private Sub Timer1_Timer()
      Timer1.Enabled = False
      If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then
        Exit sub '' I am done
      End If
      sOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
      Text1.SelText = Text1.SelText + sOutput
      Timer1.Enabled = True
    End Sub
    See if this helps.
    Marco

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center