-
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!
-
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.
-
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.
-
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.
-
No problem. As i am a VB6 newbie, and i technically *did* copy that portion of the code it was a correct response
-
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
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks