Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Problem with RUN command
Message
 
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00390391
Message ID:
00390721
Vues:
9
>Another way - take ShellExecute route. I would recommend to take a look into Ed Rauh class and program.

After I wrote this program and take a close look, I noticed two slight problems with this code.
1) Check for type(tcCommandLine) should be at the top of routine, because why we need to declare all these functions, if we return 0?
2) Each call of this function declares these functions again and again. May be it's nothing, but may be at 100th call we would have a memory blown. I vaguely recall Cetin Basoz asked a question, how can we check, if function is already Declared, but I don't remember the answers, he got...

Anyway, these are two potential problems with this code.

>
>
>********************************************************************
>*  Description.......: LaunchAppAndWait
>*  Calling Samples...: 
>*  Parameter List....: 
>*  Created by........: Ed Rauh  
>*  Modified by.......: 
>********************************************************************
>FUNCTION LaunchAppAndWait
>LPARAMETERS tcCommandLine, tuFromDir, tcWindowMode
>
>*     tcCommandLine               (R) - command line to launch
>*     tuFromDir                    (O) - Run from directory (default - CWD)
>*     tcWindowMode               (O)     - Start Application Window mode, one of (HIDE, MIN, MAX, NOR)
>*                                          (default - default setting of application)
>
>*     Returns:
>*     0 = CreateProcess didn't start what was asked
>*     1 = Process ran to completion
>*     -1= Process started but user aborted wait.  Danger - app is still running AFAIK
>
>#DEFINE cnINFINITE           0xFFFFFFFF
>#DEFINE cnHalfASecond     500     && milliseconds
>#DEFINE cnTimedOut          0x0102
>
>*     We need some API calls, declare here
>
>*     GetCurrentProcess() returns the pseudohandle of the current process
>DECLARE INTEGER GetCurrentProcess IN WIN32API AS GetCurrProc
>
>*     WaitForIdleInput() waits until the target process is idle for input
>DECLARE INTEGER WaitForInputIdle IN WIN32API AS WaitInpIdle ;
>     INTEGER nProcessHandle, ;
>     INTEGER nWaitForDuration
>
>*     WaitForSingleObject() waits until the handle in parm 1 is signalled 
>*     or the timeout period expires
>DECLARE INTEGER WaitForSingleObject IN WIN32API AS WaitOnAppExit ;
>     INTEGER hProcessHandle, ;
>     INTEGER dwTimeOut
>
>*     This API call does the work.  The parameters are as follows:
>*          lpszModuleName - ptr-> file name of module to execute.  Since we aren't launching .CPLs, do not use
>*          lpszCommandLine - ptr-> command to execute, as passed to us
>*          lpSecurityAttributesProcess - ptr-> SECURITY_ATTRIBUTES structure for Process.  Pass a null pointer
>*          lpSecurityAttributesThread - ptr-> SECURITY_ATTRIBUTES structure for first thread.  Pass a null pointer
>*          bInheritHandles - whether or not chlid inherits parent handles.  Since no SECURITY_ATTRIBUTES passed, default to FALSE
>*          dwCreateFlags - Process Creation Mode flag set.  We use the default mode at normal priority, ie 0
>*          lpvEnvironment     - ptr-> a set of environment strings as if a MULTI_SZ.  We don't set, so pass a null pointer
>*          lpszStartupDir - ptr-> the starting directory.  If none provided to us, pass a null pointer
>*          lpStartInfo - ptr-> a STARTUPINFO structure.  We use one structure member at times.
>*          lpProcessInfo - ptr-> a PROCESS_INFORMATION structure, used to return PID/PHANDLE detail.  
>*                              We use one member on return
>DECLARE SHORT CreateProcess IN WIN32API AS CrPr ;
>     STRING lpszModuleName, ;
>     STRING @lpszCommandLine, ;
>     STRING lpSecurityAttributesProcess, ;
>     STRING lpSecurityAttributesThread, ;
>     SHORT bInheritHandles, ;
>     INTEGER dwCreateFlags, ;
>     STRING lpvEnvironment, ;
>     STRING lpszStartupDir, ;
>     STRING @lpStartInfo, ;
>     STRING @lpProcessInfo
>
>IF TYPE('tcCommandLine') # 'C'
>
>     *     Command line must be a character string
>     RETURN 0
>
>ENDIF
>IF TYPE('tuFromDir') # 'C'
>
>     *     If not a character string, pass a null pointer, defaulting to Current Working Dir
>     tuFromDir = 0
>
>ELSE
>
>     *     Otherwise, null pad the string
>     tuFromDir = tuFromDir + CHR(0)
>
>ENDIF
>IF TYPE('tcWindowMode') # 'C'
>
>     *     If not passed, set to null string
>     tcWindowMode = ''
>
>ELSE
>
>     *     Translate the passed window mode to uppercase
>     tcWindowMode = UPPER(tcWindowMode)
>
>ENDIF
>
>LOCAL nStartedProcessHandle, uResult, cProcessInfo, cStartUpInfo
>
>*     Make default Structures for the CreateProcess call
>*
>*     ProcessInfo - 4 bytes, a Process handle, a Thread Handle, a (DWORD) ProcessId and a (DWORD) ThreadID
>*                         we save the Process handle and return it to caller in tnReturnProcessHandle
>
>cProcessInfo = REPL(CHR(0),16)
>
>*     StartUpInfo is a 68 byte long complex structure;  we either have 68 bytes with a cb member (byte 1) 68
>*     or with cb of 68, dwFlag low order byte (byte 45) of 1, and low order byte wShowWindow (byte 49) set to
>*     the SW_ value appropriate for the Window Mode desired.
>
>DO CASE
>CASE tcWindowMode = 'HIDE'
>
>     *     Hide - use STARTF_USESHOWFLAG and value of 0
>     cStartUpInfo = CHR(68) + ;
>                         REPL(CHR(0),43) + ;
>                         CHR(1) + ;
>                         REPL(CHR(0),23)
>
>CASE tcWindowMode = 'NOR'
>
>     *     Normal - use STARTF_USESHOWFLAG and value of 1
>     cStartUpInfo = CHR(68) + ;
>                         REPL(CHR(0),43) + ;
>                         CHR(1) + ;
>                         REPL(CHR(0),3) + ;
>                         CHR(1) + ;
>                         REPL(CHR(0),19)
>
>CASE tcWindowMode = 'MIN'
>
>     *     Minimize - use STARTF_USESHOWFLAG and value of 2
>     cStartUpInfo = CHR(68) + ;
>                         REPL(CHR(0),43) + ;
>                         CHR(1) +  ;
>                         REPL(CHR(0),3) + ;
>                         CHR(2) + ;
>                         REPL(CHR(0),19)
>
>CASE tcWindowMode = 'MAX'
>
>     *     Maximize - use STARTF_USESHOWFLAG and value of 3
>     cStartUpInfo = CHR(68) + ;
>                         REPL(CHR(0),43) + ;
>                         CHR(1) +  ;
>                         REPL(CHR(0),3) + ;
>                         CHR(3) + ;
>                         REPL(CHR(0),19)
>
>*     Other options exist - see WINBASE.H for values
>
>OTHERWISE
>
>     *     Use default of application
>     cStartUpInfo = CHR(68) + REPL(CHR(0),67)
>
>ENDCASE
>
>*     Do it now!
>uResult = CrPr(     0, ;
>                    tcCommandLine, ;
>                    0, 0, 0, 0, 0, ;
>                    tuFromDir, ;
>                    @cStartUpInfo, ;
>                    @cProcessInfo)
>
>IF uResult = 1
>
>     *     CreateProcess() started our app, but we have to wait until it finishes loading
>
>     *     Strip the process handle from the PROCESS_INFORMATION structure
>
>     nStartedProcessHandle = (((ASC(SUBST(cProcessInfo,4,1))*256) + ;
>                                        ASC(SUBST(cProcessInfo,3,1)))*256 + ;
>                                        ASC(SUBST(cProcessInfo,2,1)))*256 + ;
>                                        ASC(LEFT(cProcessInfo,1))
>
>     *     It's been launched;  wait until we're idling along
>
>     =WaitInpIdle(GetCurrProc(),cnINFINITE)
>
>     *     As long as the other process exists, wait for it
>
>     DO WHILE WaitOnAppExit(nStartedProcessHandle, cnHalfASecond) = cnTimedOut
>
>          *     Give us an out in case the other app hangs - lets the user quit via 
>          IF INKEY() = 27
>               *     Still running but we aren't waiting - return a -1 as a warning
>               uResult = -1
>               EXIT
>          ENDIF
>
>     ENDDO
>
>ELSE
>
>     *     Return 0 to indicate failure
>     uResult = 0
>
>ENDIF
>RETURN uResult
>
If it's not broken, fix it until it is.


My Blog
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform