Saturday, June 02, 2012 1:06 AM
I think this is fairly simple but I can't seem to get the syntax correct.
I want to launch a vfp app passing 4 parameters.
The parameters are variables that contain information such as the folder location, username, password etc.
The problem is I am not sure how to build the paramter string.
mparam = '"'+parm1+'",'+'"'+parm2+'",'+'"'+parm3+'",'+'"'+parm4+'"'
declare integer ShellExecute in shell32.dll ;
integer hndWin, ;
string cAction, ;
string cFileName, ;
string cParams, ;
string cDir, ;
nerror = ShellExecute(0,'open','myvfp.exe',mparam,"",1)
Any help greatly appreciated.
Saturday, June 02, 2012 5:19 AMAnswerer
Check below link there is sample given for How to Pass Parameter to VFP Exe.
- Proposed As Answer by Pavel CelbaMicrosoft Community Contributor, Moderator Saturday, June 02, 2012 11:34 AM
- Marked As Answer by Stuman99 Monday, June 04, 2012 9:06 PM
Monday, June 04, 2012 6:49 AMAnswerer
although Sergeys blog as mentioned in Kalpeshs answer is always an excellent source I want to add some alternative ways on how to start another exe from within your app (instead of SHELLEXECUTE).
The way how to call another exe depends on what your first app shall do during the called exe is running.
So....using Sergeys description about converting the params to strings and assuming, that your app shall continue working (=2 parallel running exe where you can switch with ALT+TAB) you can do something like this:
TEXT TO lcRun TEXTMERGE NOSHOW PRETEXT 1+2+4+8 RUN /N my2ndapp.exe <<liIntegerVal>> <<lcCharVal>> ENDTEXT &lcRun
However, if you want to take care, that your 1. exe will stop working until the called exe was closed, then you might use a routine I found some years ago. I can't give credit to the original programmer of that code because I don't remember where it came from.
I found the source once more: Code comes from the late Ed Rauh and can be found on UT!
So part 1 shows how to call the function (param 3 know 4 different values: HIDE,NOR,MIN,MAX) :
lcFile = [my2ndapp.exe] lcPara = TRANSFORM( liIntegerVal ) ; + ALLTRIM( lcStringVal ) lcDir = SYS( 5 ) + SYS( 2003 ) LaunchExeAndWait(lcFile + [ ] + lcPara,lcDir,[NOR])
and here comes the function:
FUNCTION LaunchExeAndWait LPARAMETERS pcCommandLine, puFromDir, pcWindowMode * pcCommandLine (R) - command line to launch * puFromDir (O) - Run from directory (default - CWD) * pcWindowMode (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('pcCommandLine') # 'C' * Command line must be a character string RETURN 0 ENDIF IF TYPE('puFromDir') # 'C' * If not a character string, pass a null pointer, defaulting to Current Working Dir puFromDir = 0 ELSE * Otherwise, null pad the string puFromDir = puFromDir + CHR(0) ENDIF IF TYPE('pcWindowMode') # 'C' * If not passed, set to null string pcWindowMode = '' ELSE * Translate the passed window mode to uppercase pcWindowMode = UPPER(pcWindowMode) 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 pcWindowMode = 'HIDE' * Hide - use STARTF_USESHOWFLAG and value of 0 cStartUpInfo = CHR(68) + ; REPL(CHR(0),43) + ; CHR(1) + ; REPL(CHR(0),23) CASE pcWindowMode = '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 pcWindowMode = '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 pcWindowMode = '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, ; pcCommandLine, ; 0, 0, 0, 0, 0, ; puFromDir, ; @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 <Esc> 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
Gruss / Best regards -Tom 010101100100011001010000011110000101001001101111011000110110101101110011
- Edited by Tom BorgmannEditor Monday, June 04, 2012 7:35 AM Info added
Monday, June 04, 2012 9:10 PM
The article explained everything I needed. Spaces and not commas as separators was my big problem.
Monday, June 04, 2012 9:11 PM
I will review the code, I really appreciate the response!