Getting info from a process

BlitzMax Forums/BlitzMax Programming/Getting info from a process

degac(Posted 2007) [#1]
I'm trying to create (for testing only) a gui interface for UPX.
I would like to retrieve the status of working while UPX is compressing a file.
If you use UPX from command line you will see a progress bar and a % of progress.
How can I have this info and use this in my program?
This is a (piece of code) I'm using
exec$=(AppDir+"\upx.exe -v target.exe")
Local myproc:TProcess = TProcess.Create (exec$ , 0)
Local bytes:Byte[]
Local result:String=""
If myproc
	While True
		bytes = myproc.pipe.readpipe()
		If bytes
			result:+ string.frombytes(bytes , Len bytes)
				
		End If
		If Not myproc.status() Exit
		Print ":"+result+":"
		Delay 10
	Wend
End If
Print "Final result: "+result
myproc.Close()


The Delay 10 is only to speed down the thing.

Second question: I have - at the end - a string stored in result with the final infos, but in case of error (ie: file already packed) I have only this output
Final result:                        Ultimate Packer for eXecutables
    Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.03w       Markus Oberhumer, Laszlo Molnar & John Reiser    Nov 7th 2006

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------

Packed 1 file: 0 ok, 1 error.

While if I run from CLI I get
                       Ultimate Packer for eXecutables
    Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.03w       Markus Oberhumer, Laszlo Molnar & John Reiser    Nov 7th 2006

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: target.exe: AlreadyPackedException: already packed by UPX

Packed 1 file: 0 ok, 1 error.

It seems that some output is 'lost'...
Any suggestions?


SebHoll(Posted 2007) [#2]
This is because processes are actually run with two pipes: StandardIO (in Pub.FreeProcess, this is myproc.pipe); and StandardError (in Pub.FreeProcess, this is myproc.err). Any output that represents an error is sent to the special (.err) pipe so that it can be identified and processed separately to normal output. Therefore, you will need to catch data from this pipe too.

Try something like (untested):

exec$=(AppDir+"\upx.exe -v target.exe")
Local myproc:TProcess = TProcess.Create (exec$ , 0)
Local bytes:Byte[]
Local result:String=""
If myproc
	While True
		bytes = myproc.pipe.readpipe()
		If bytes
			result:+ string.frombytes(bytes , Len bytes)				
		End If

		bytes = myproc.err.readpipe()	'Add this to catch any output from the StandardError pipe
		If bytes
			result:+ string.frombytes(bytes , Len bytes)		
		End If
		If Not myproc.status() Exit
		Print ":"+result+":"
		Delay 10
	Wend
End If
Print "Final result: "+result
myproc.Close()
You may also want to read this thread where we were explaining a lot of the problems you may encounter with using Pub.FreeProcess, including what I've mentioned above.


degac(Posted 2007) [#3]
Ohhh! Thanks!
I've missed that thread about Pub.Process!!!