RunProgram, ReadProgram, and monitor its window's title?

Just starting out? Need help? Post your questions and find answers here.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

RunProgram, ReadProgram, and monitor its window's title?

Post by Seymour Clufley »

I'm using this code to run an exe utility by command line.

Code: Select all

Compiler = RunProgram(exe,"-v "+c34+u+c34+" --console-title",TempFolder, #PB_Program_Open | #PB_Program_Read)
If Compiler
  While ProgramRunning(Compiler)
    If AvailableProgramOutput(Compiler)
      Debug ReadProgramString(Compiler)
    EndIf
  Wend
  CloseProgram(Compiler) ; Close the connection to the program
EndIf
The parameter --console-title makes the utility report its progress percentage in its console window's title, which updates constantly while the utility does it work.

I need to keep track of that progress percentage. Is there a way - ideally a cross-platform way - to read the window title of a console utility?

Thank you.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
infratec
Always Here
Always Here
Posts: 7781
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: RunProgram, ReadProgram, and monitor its window's title?

Post by infratec »

Windows only:

Code: Select all

Global RunProgramWindowHandle.i

Procedure.i EnumWindowsCallBack(hwnd.i, param.i)
  
  Protected Result.i, PID.l, Length.i
  
  
  Result = #True
  If GetWindowThreadProcessId_(hwnd, @PID)
    If PID = param
      RunProgramWindowHandle = hwnd
      Result = #False
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Compiler = RunProgram("cmd","","", #PB_Program_Open | #PB_Program_Read)
If Compiler
  
  Delay(200) ; to allow the window to appear
  
  EnumWindows_(@EnumWindowsCallBack(), ProgramID(Compiler))
  
  While ProgramRunning(Compiler)
    If AvailableProgramOutput(Compiler)
      
      NewTitle$ = Space(#MAX_PATH)
      Length = GetWindowText_(RunProgramWindowHandle, @NewTitle$, #MAX_PATH)
      If Length
        If Title$ <> NewTitle$
          Title$ = NewTitle$
          Debug "Title: " + Title$
        EndIf
      EndIf
      
      Debug ReadProgramString(Compiler)
    EndIf
  Wend
  CloseProgram(Compiler) ; Close the connection to the program
EndIf
Last edited by infratec on Fri Oct 23, 2020 5:45 pm, edited 1 time in total.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: RunProgram, ReadProgram, and monitor its window's title?

Post by Seymour Clufley »

Thanks very much!
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
infratec
Always Here
Always Here
Posts: 7781
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: RunProgram, ReadProgram, and monitor its window's title?

Post by infratec »

Extended version without global, without delay and immediate response:

Code: Select all

EnableExplicit


Structure RunProgramExtendedStructure
  ProgramID.i
  WindowHandle.i
EndStructure


Procedure.i EnumWindowsCallBack(hwnd.i, param.i)
  
  Protected Result.i, PID.l, Length.i, *RunProgramExtended.RunProgramExtendedStructure
  
  
  Result = #True
  *RunProgramExtended = param
  If GetWindowThreadProcessId_(hwnd, @PID)
    If PID = *RunProgramExtended\ProgramID
      *RunProgramExtended\WindowHandle = hwnd
      Result = #False
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Define Compiler.i, *Buffer, Length.i, Title$, NewTitle$
Define RunProgramExtended.RunProgramExtendedStructure


Compiler = RunProgram("cmd","","", #PB_Program_Open | #PB_Program_Read)
If Compiler
  
  *Buffer = AllocateMemory(#MAX_PATH * SizeOf(Character), #PB_Memory_NoClear)
  If *Buffer
    
    RunProgramExtended\ProgramID = ProgramID(Compiler)
    
    While ProgramRunning(Compiler)
      
      If RunProgramExtended\WindowHandle = 0
        EnumWindows_(@EnumWindowsCallBack(), @RunProgramExtended)
      Else
        Length = GetWindowText_(RunProgramExtended\WindowHandle, *Buffer, #MAX_PATH)
        If Length
          ;Debug Length
          NewTitle$ = PeekS(*Buffer, Length)
          If Title$ <> NewTitle$
            Title$ = NewTitle$
            Debug "Title: " + Title$
          EndIf
        EndIf
      EndIf
      
      Length = AvailableProgramOutput(Compiler)
      If Length
        If ReadProgramData(Compiler,*Buffer, Length)
          Debug PeekS(*Buffer, Length, #PB_UTF8|#PB_ByteLength)
        EndIf
      EndIf
    Wend
    
    FreeMemory(*Buffer)
  EndIf
  
  CloseProgram(Compiler) ; Close the connection to the program
EndIf
You can click with left/right mousebutton inside the window to see the changing title.
Last edited by infratec on Fri Oct 23, 2020 5:45 pm, edited 1 time in total.
Seymour Clufley
Addict
Addict
Posts: 1267
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: RunProgram, ReadProgram, and monitor its window's title?

Post by Seymour Clufley »

Again, thank you very much.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Post Reply