Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Run without Dos box
Message
 
À
23/09/1998 00:50:57
Information générale
Forum:
Visual FoxPro
Catégorie:
FoxPro 2.x
Divers
Thread ID:
00139702
Message ID:
00139849
Vues:
38
David,

I pciked this up off of UT, it is not my work and I don't have the name of the original author. I wish I did. I believe I found it in the files section here on UT. I've played around with it and it seems to work.

I don't think the code pasted to well. I'll see if I can send it as an email.


The following code will launch a DOS or Windows executable without using the RUN command; it gives some control over the starting window of the executable, and waits pretty reliably on termination, using the Process Handle rather than a Window Handle to test for completion. My thanks to dozens of instances of various applets like NOTEPAD and EDLIN, without whom this code would never have been debugged:
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



>I remember seeing a technique for doing a RUN command without seeing the DOS window pop up.
>I want to synchronise a client pc to the NT server using
>
run /n net time \\server /yes
>but not see the box.
>BTW, is there another way of doing this seemlessly?
>TIA
Bud Wheeler
Vision Data Solutions, Inc.
Microsoft Partner

http://www.visionpace.com
Http://www.BudWheeler.com
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform