Announcement

Collapse
No announcement yet.

Shellexecute - how to set wait for shell process to complete

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Shellexecute - how to set wait for shell process to complete

    Hi

    I'm needing some help in getting a Shell process (ShellExecute another external program) to wait until this external program gets completed, then only the main program
    can go on to the next stage. I have searched the forum and found something close to this requirement but still can't get the process complete
    before going to the next stage

    The following code came from https://forum.powerbasic.com/forum/u...012#post710012

    Code:
    ' Shell and wait2.bas
    '
    #COMPILE EXE
    #INCLUDE "win32api.inc"
    
    
    FUNCTION shellexx(app$,args$,OPT WaitForInputIdle_true&) AS DWORD
       'if WaitForInputIdle_true& not supplied...assumes app will terminate itself
       LOCAL zFl_to_run,zArgs,zTarget_dir AS ASCIZ * 100
       zFl_to_run=app$
       zArgs=args$
       'zTarget_dir = "c:\"
       LOCAL si AS ShellExecuteInfo
       si.cbSize       = SIZEOF(si)
       si.fmask        = %SEE_MASK_NOCLOSEPROCESS
       si.hWnd         = %NULL 'parent window
       si.lpFile       = VARPTR(zFl_to_run)
       si.lpParameters = VARPTR(zArgs)
       'si.lpDirectory  = VARPTR(zTarget_dir) '%NULL
       si.nShow        = %SW_SHOWNORMAL
       si.hProcess     = 0
    
       IF ISTRUE ShellExecuteEx(si) THEN
            ' function succeeded and returned
          IF ISMISSING(WaitForInputIdle_true&) THEN
              'assume the shell'd app closes itself
          ELSE
              '0 delay means infinite    30000
             WaitForInputIdle(si.hProcess,0)
           ' essential to helping SetForegroundWindow not to happen
           ' prematurely and get overridden by shell'd app
             SLEEP(1000)
             hWndcon& = GetConsoleWindow()
             SetForegroundWindow( hWndcon& )
             FUNCTION=si.hProcess
          END IF
       ELSE
          ? "problem in shellexec"
       END IF  '
    END FUNCTION
    
    
    
    FUNCTION PBMAIN () AS LONG
    
       app$="notepad.exe"
       args$="a textfile.txt"
       hProc& = shellexx(app$,args$,1)
    
       ? "All done ? "
       TerminateProcess(hProc&,0)
    END FUNCTION

    As you see that immediately after this line
    hProc& = shellexx(app$,args$,1)

    the main program will display the " All done ? " prompt


    I wonder if there is a way that we can allow the external program to complete its task before it can revert back to the main program where the
    prompt " All done ? " comes in.
    As far as I could remember, in VB.Net there is a way to stall the main program, until ShellExecute process is completed.

    Thanks in advance for your help!




  • #2
    In VB.Net they have a process class which we can shell and wait
    according to http://www.vbforums.com/showthread.p...-wait-and-exit

    Is there an equivalent method in Powerbasic?


    Code:
    Dim psi As New ProcessStartInfo("fileName", "arguments")
        Dim p As New Process
        p.StartInfo = psi
        p.WaitForExit()
        p.Start()

    Comment


    • #3
      There may be something you can use here:

      https://forum.powerbasic.com/forum/u...shellexecuteex

      Comment


      • #4
        Tim,
        Borje, has some cool code around here for using a shared DLL to communicate between apps if they are both your apps of course.

        Also IsWindowVisible may be helpful with the handle of the app in question. ShellExecuteEx gives you that handle.

        Comment


        • #5
          Tim,
          Change
          WaitForInputIdle(si.hProcess,0)
          for
          WaitForSingleObject(si.hProcess, %INFINITE)

          Comment


          • #6
            Thanks Pierre, that works perfectly!

            Thanks all others for your time and assistance!

            Comment


            • #7
              Hi again,
              just one more question how to trap error messages that may have arise from this program run
              for example, I got this message when the external program "menuprog.exe" does not exist


              Click image for larger version

Name:	err.png
Views:	64
Size:	20.4 KB
ID:	777351


              Code:
              ' Shell and wait3.bas
              #COMPILE EXE
              #INCLUDE "win32api.inc"
              
              FUNCTION shellexx(app$,args$,OPT WaitForInputIdle_true&) AS DWORD
                 'if WaitForInputIdle_true& not supplied...assumes app will terminate itself
                 LOCAL zFl_to_run,zArgs,zTarget_dir AS ASCIZ * 100
                 zFl_to_run=app$
                 zArgs=args$
                 'zTarget_dir = "c:\"
                 LOCAL si AS ShellExecuteInfo
                 si.cbSize       = SIZEOF(si)
                 si.fmask        = %SEE_MASK_NOCLOSEPROCESS
                 si.hWnd         = %NULL 'parent window
                 si.lpFile       = VARPTR(zFl_to_run)
                 si.lpParameters = VARPTR(zArgs)
                 'si.lpDirectory  = VARPTR(zTarget_dir) '%NULL
                 si.nShow        = %SW_SHOWNORMAL
                 si.hProcess     = 0
              
              
                              CALL ShellExecuteEx( si )
                              IF si.hProcess THEN
                                  CALL WaitForSingleObject( si.hProcess, %INFINITE )
                              END IF
              
              
              END FUNCTION
              
              FUNCTION PBMAIN () AS LONG
                 app$="menuprog.exe"
                 args$=""
                 hProc& = shellexx(app$,args$)
                 ? "All done ? "
                 TerminateProcess(hProc&,0)
              END FUNCTION
              I need to trap these error messages so that I can make custom messages for them
              to inform the end users in a better fashion. Thanks in advance

              Comment


              • #8
                Add SEE_MASK_FLAG_NO_UI to si.mask

                Code:
                si.fmask = %SEE_MASK_NOCLOSEPROCESS OR %SEE_MASK_FLAG_NO_UI 'SEE_MASK_FLAG_NO_UI for no error message
                LOCAL LastError AS DWORD
                IF ShellExecuteEx(si) = %FALSE THEN
                  LastError = GetLastError()
                  MessageBox(%HWND_DESKTOP, "Error #" & STR$(LastError) & " occured!", _
                             "ShelExecute", %MB_ICONERROR OR %MB_OK OR %MB_TOPMOST)
                END IF
                IF si.hProcess THEN
                  WaitForSingleObject(si.hProcess, %INFINITE)
                END IF

                Comment


                • #9
                  And for those who do not already know, FormatMessage() can get the corresponding error text...

                  Code:
                  '_____________________________________________________________________________
                  
                  FUNCTION WinError$(BYVAL ErrorCode AS DWORD) AS STRING
                   LOCAL pzError  AS ASCIIZ POINTER 'Max is 64K
                   LOCAL ErrorLen AS DWORD
                  
                   ErrorLen = FormatMessage(%FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_ALLOCATE_BUFFER, _
                                            BYVAL %NULL, ErrorCode, %NULL, BYVAL VARPTR(pzError), %NULL, BYVAL %NULL)
                   IF ErrorLen THEN
                     FUNCTION = "Error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ") : " & @pzError
                     LocalFree(pzError)
                   ELSE
                     FUNCTION = "Unknown error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ")"
                   END IF
                  
                  END FUNCTION
                  '_____________________________________________________________________________

                  Comment


                  • #10
                    Thanks Pierre, you are absolutely amazing in programming!

                    Comment


                    • #11
                      Just for reference, PB offers both a synchronous and asynchronous version of the shell command, one will wait, the other will not. I've used both in my programs before, no need for extra includes/other programs.
                      http://www.softcon.com]


                      for hosting/internet


                      access.

                      Comment


                      • #12
                        Tim, I am a lil late to the party but I put my error handling with your code to demonstrate an easy way to catch errors.
                        Attached Files
                        Engineer's Motto: If it aint broke take it apart and fix it

                        "If at 1st you don't succeed... call it version 1.0"

                        "Half of Programming is coding"....."The other 90% is DEBUGGING"

                        "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                        Comment

                        Working...
                        X