[PB5.20 Beta12] RunProgram() not valid

Windows specific forum
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

[PB5.20 Beta12] RunProgram() not valid

Post 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?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Shardik
Addict
Addict
Posts: 2069
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

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

Post 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.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
JHPJHP
Addict
Addict
Posts: 2273
Joined: Sat Oct 09, 2010 3:47 am

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

Post 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.
Last edited by JHPJHP on Mon Sep 02, 2013 12:59 am, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

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

Post 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).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post by IdeasVacuum »

Thanks for the tip PB - on this occasion it doesn't help though. :?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
JHPJHP
Addict
Addict
Posts: 2273
Joined: Sat Oct 09, 2010 3:47 am

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

Post 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

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
JHPJHP
Addict
Addict
Posts: 2273
Joined: Sat Oct 09, 2010 3:47 am

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

Post 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)

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.........
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
JHPJHP
Addict
Addict
Posts: 2273
Joined: Sat Oct 09, 2010 3:47 am

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

Post 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

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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......
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply