Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Run without Dos box
Message
General information
Forum:
Visual FoxPro
Category:
FoxPro 2.x
Miscellaneous
Thread ID:
00139702
Message ID:
00140086
Views:
40
>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.
>

That's one of mine; I've been playing around with a few refinements. The code here was posted in a FAQ a week or so ago.

There are a few improvements in the works; the PROCESSINFO structure contains both a ProcessHandle and a ThreadHandle that ought to be released explicily with CloseHandle() to avoid memory bleeds caused by keeping process and thread objects floating around; not much of an issue unless you have a very minimal memory configuration and run CreateProcess() a whole lot. (Win32 keeps process and thread objects open as long as there are unreleased handles; even if they go out of scope and drop from memory the reference count is not decremented unless CloseHandle() is called.)

I'll probably be releasing an API-based process class once I finish playing around with some added functionality (do things like check termination status and properly release any handles when the VFP object is released.)

>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
EMail: EdR@edrauh.com
"See, the sun is going down..."
"No, the horizon is moving up!"
- Firesign Theater


NT and Win2K FAQ .. cWashington WSH/ADSI/WMI site
MS WSH site ........... WSH FAQ Site
Wrox Press .............. Win32 Scripting Journal
eSolutions Services, LLC

The Surgeon General has determined that prolonged exposure to the Windows Script Host may be addictive to laboratory mice and codemonkeys
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform