Page 1 of 1

[PB5.20 Beta12] RunProgram() not valid

Posted: Sat Aug 31, 2013 5:24 am
by IdeasVacuum
I'm running the console version of 7zip via Run Program:

Code: Select all

i7zip = RunProgram("C:\7zip\7za.exe", " a -t7z my_archive.7z C:\MyTemp", "C:\", #PB_Program_Hide | #PB_Program_Read)

          While ProgramRunning(i7zip)

                    Debug AvailableProgramOutput(i7zip)
                    Debug ReadProgramString(i7zip)
          Wend
End
It creates the .7z file perfectly, but the PB compiler flags ProgramRunning() with the message: [ERROR] The specified 'Program' is not valid and indeed the output from 7za.exe is not captured. Anyone hit this and found a solution?

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sat Aug 31, 2013 5:37 am
by IdeasVacuum
Well it seems that the #PB_Program_Open must be used, though the wording of the Help doesn't suggest this :shock:

Code: Select all

 *Buffer = AllocateMemory(1024 * SizeOf(character))

   i7zip = RunProgram("C:\7zip\7za.exe", " a -t7z my_archive.7z C:\MyTemp", "C:\", #PB_Program_Open | #PB_Program_Hide | #PB_Program_Read)
If i7zip

          While ProgramRunning(i7zip)

                    If AvailableProgramOutput(i7zip)

                           ReadProgramData(i7zip,*Buffer,1024)
                                 Debug PeekS(*Buffer, 1024, #PB_UTF8)
                    EndIf
          Wend

          CloseProgram(i7zip)
EndIf

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sat Aug 31, 2013 6:53 am
by Shardik
IdeasVacuum wrote:Well it seems that the #PB_Program_Open must be used, though the wording of the Help doesn't suggest this :shock:
Sorry, I am not a native speaker, but I find PB's help instructions quite clear:
PB help for RunProgram() wrote:The following functions may be used with a program that has been executed with the #PB_Program_Open flag:

- IsProgram(): check if the program number represents a valid program executed by RunProgram().
- ProgramID(): returns the OS ProcessID for the program.
- ProgramRunning(): check if the program is still running.
- WaitProgram(): wait for the program to end.
- KillProgram(): terminate the program.
- ProgramExitCode(): get the exitcode of the program.
- CloseProgram(): close the connection to the program.

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sat Aug 31, 2013 1:29 pm
by IdeasVacuum
You are quite right Shardik, and English is my native language too :shock:

In my defence, given the lack of coffee input at the time:

#PB_Program_Open : Open the program to communicate with it or get information about it. [Nope, don't want to do that]
#PB_Program_Read : Read the programs console output. (stdout) [Yep, that's what I want]

I have hit another problem. When 7zip is run on it's own, it's output is file-by-file in the console window. PB though does not pick this data up until the entire job is complete - so can't use the output as a way to report process progress.

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 7:58 am
by JHPJHP
It looks like PureBasic already has this covered (ReadProgramString / ReadProgramData):
ReadProgramString

Note: This function waits until there is data available to read from the program. To prevent this wait, AvailableProgramOutput() may be used first to check if there is something to read. This function also waits until a full line of output is available. If not line-based or raw output is to be read, ReadProgramData() may be used.

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 10:02 am
by PB
> [Nope, don't want to do that]

Actually, you do. :) You need to both #PB_Program_Open the
program, and also #PB_Program_Read any of its data output.

Also, try adding Delay(1000) after the RunProgram() command.
One of my older apps needed such a short delay to capture the
output correctly (and I also used Open|Read for the flags too).

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 11:03 am
by IdeasVacuum
But it looks like PureBasic already has this covered(ReadProgramString / ReadProgramData)
If you take a look at the snippet I posted using ReadProgramData, it's not the solution because PB is delivering the output when 7zip has finished it's work - so instead of a line-by-line progress we just get all of the progress info displayed in one lump once 7zip has finished. So, definitely going to look into your Console stuff, thank you JHPJHP.

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 11:07 am
by IdeasVacuum
Thanks for the tip PB - on this occasion it doesn't help though. :?

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 4:28 pm
by JHPJHP
Try the following and see what you get:

Code: Select all

; *Buffer = AllocateMemory(1024 * SizeOf(character))
i7zip = RunProgram("C:\7zip\7za.exe", " a -t7z my_archive.7z C:\MyTemp", "C:\", #PB_Program_Open | #PB_Program_Hide | #PB_Program_Read)

If i7zip
  While ProgramRunning(i7zip)
    If AvailableProgramOutput(i7zip)
      a + 1
      Debug Str(a) + ". " + ReadProgramString(i7zip)
      ; ReadProgramData(i7zip,*Buffer,1024)
      ; Debug PeekS(*Buffer, 1024, #PB_UTF8)
    EndIf
  Wend
  CloseProgram(i7zip)
EndIf
Debug Output:
1.
2. 7-Zip 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
3.
4. Scanning
5.
6. Updating archive my_archive.7z
7.
8. Compressing Images\dance1.gif
9. Compressing Images\dance2.gif
10. Compressing Images\dance3.gif
11. Compressing Images\watermark.gif
12. Compressing Images\about.png
...
124.
125. Everything is Ok

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 6:45 pm
by IdeasVacuum
....Unfortunately JHPJHP, essentially the same as my code snippet using ReadProgramData().
Start RunProgram(), no output, end RunProgram(), all output in one lump. Can't actually use ReadProgramString() anyway because it is ASCII only.

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Sun Sep 01, 2013 8:47 pm
by JHPJHP
I feel good about this one, as long as you don't mind the additional overhead: :wink:

Code: Select all

*Buffer = AllocateMemory(2048 * SizeOf(character))
i7zip = RunProgram("C:\7zip\7za.exe", " a -t7z my_archive.7z C:\MyTemp", "C:\", #PB_Program_Open | #PB_Program_Hide | #PB_Program_Read)

If i7zip
  While ProgramRunning(i7zip)
    If AvailableProgramOutput(i7zip)
      FileName.s = ""
      
      Repeat
        ReadProgramData(i7zip, *Buffer, 1)
        Character.s = PeekS(*Buffer, -1, #PB_UTF8)
        
        If Character = Chr(10) : Break : Else : FileName + Character : EndIf
        
      ForEver
      Debug Str(a) + ". " + FileName
      a + 1
    EndIf
  Wend
  CloseProgram(i7zip)
EndIf
FreeMemory(*Buffer)

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Mon Sep 02, 2013 1:59 am
by IdeasVacuum
Nice try JHPJHP, but PB is not aware of AvailableProgramOutput() until 7zip has actually finished, so we see the output as one giant lump instead of line-by-line.

Now, when 7zip is run independantly, it does output to the console line-by-line, so at the moment I'm thinking that maybe AvailableProgramOutput() does not check frequently enough or perhaps the app using it needs to have a higher process priority. Ah - I should try using it in a thread.........

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Mon Sep 02, 2013 2:24 am
by IdeasVacuum
Same issue using a thread:

Code: Select all

Enumeration
#WinReport
#EdReport
EndEnumeration

Procedure RunIt(*Val)

 sReport.s = ""
 sOutput.s = ""
   i7zip.i
   iSize.i = (128 * SizeOf(character))
   *Buffer = AllocateMemory(iSize)

   i7zip = RunProgram("C:\7zip\7za.exe", " a -t7z my_archive.7z C:\MyTemp", "C:\", #PB_Program_Open | #PB_Program_Hide | #PB_Program_Read)
If i7zip

          While ProgramRunning(i7zip)

                    If AvailableProgramOutput(i7zip)

                           ReadProgramData(i7zip, *Buffer, iSize)

                           sOutput = PeekS(*Buffer, iSize, #PB_UTF8)
                           sReport = sReport + sOutput
                           SetGadgetText(#EdReport, sReport)
                          InvalidateRgn_(GadgetID(#EdReport),#Null,#False)
                              FillMemory(*Buffer, iSize, '0', #PB_Character)

                    EndIf
          Wend

          CloseProgram(i7zip)
EndIf

EndProcedure

Procedure OpenWinReport()

                  OpenWindow(#WinReport, 0, 0, 515, 465, "RunIt Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
                EditorGadget(#EdReport, 0, 0, 515, 465)
EndProcedure

OpenWinReport()

   iThread.i = CreateThread(@RunIt(), *Val)
If(iThread) : ThreadPriority(iThread, 31) : EndIf

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

End

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Mon Sep 02, 2013 5:07 am
by JHPJHP
*** Update ***

Your not going to believe this... I just tested it on a Windows XP box, and I'm seeing what your seeing, but on my Windows 7 computer the results are positive; you just can't win today, sorry - and ignore the remarks below!

*** Update ***

I'm getting completely different results...

When I posted the ReadProgramString solution, you can see by my debug report that it was reading line by line, but you weren't seeing that from your tests.

And because of the Unicode requirements, your next option was to use ReadProgramData...

When I first tested with ReadProgramData I was getting the same results as you, but that was because I was reading the entire buffer at once. But when I adjusted my code to read 1 character at a time (not knowing where the carriage return was) my debug results were successful - identical to the debug results from ReadProgramString.

Is this another XP / Windows 7 thing I wonder, or maybe a version difference with 7Zip?

Debug Output:
0.
1. 7-Zip 9.13 beta Copyright (c) 1999-2010 Igor Pavlov 2010-04-15
2. Scanning
3.
4. Creating archive my_archive.7z
5.
6. Compressing Images\dance1.gif
7. Compressing Images\dance2.gif
8. Compressing Images\dance3.gif
9. Compressing Images\watermark.gif
10. Compressing Images\about.png
11. Compressing Images\about_fuzzy.png
12. Compressing Images\background.png
...
122.
123. Everything is Ok

Re: [PB5.20 Beta12] RunProgram() not valid

Posted: Mon Sep 02, 2013 1:15 pm
by IdeasVacuum
That's sort of good news and bad news rolled into one :D I can't see why there is a difference between XP and 7 in this case, but I'm sure Fred would know......