/*
----------------------------------------------------------------
Filename.....: runProcess.cc
ClassName....: runProcess
Programmer...: Rick Miller with most of the code derived
from Jim Sare's :dUFLP:RunWait.prg.
Date.........: June 24, 2008.
Purpose......: run a command line in various ways.
Notes........: See Notes below.
Written for..: dBASE 32-bit.
Rev. History.: None.
Dependencies.: None.
API Calls....: See x_InitializeExterns method.
Called by....: Any.
Usage........: set procedure additive.
Example......: See Example below.
----------------------------------------------------------------
Example:
----------------------------------------------------------------
oRef = new runProcess()
// command line to run notepad.exe.
cCommand = [notepad.exe]
// execute the command line.
oRef.run(cCommand)
// command line to unzip a file with 7za.exe.
cCommand = fullpath + [\] + [7za.exe e ] +;
chr(34) + fullpath + [\] + filename + chr(34) +;
[ ] +;
chr(34) + fullpathToextractfolder + chr(34)
// execute the command line.
oRef.runHiddenWait(cCommand)
// clear out the runProcess object.
oRef.release()
oRef := null
----------------------------------------------------------------
Notes:
----------------------------------------------------------------
1) all run??? methods default to running from the current
directory when the 2nd parameter is not passed.
2) the runHidden, or the runHiddenWait method
should only be used for a command line
that will run and exit on it's own.
----------------------------------------------------------------
Properties: None.
----------------------------------------------------------------
Methods:
----------------------------------------------------------------
close() call to release(),
close procedure file.
release() release object.
run(<char>[, <char> dir]) run in normal window.
runHidden(<char>[, <char> dir]) run in hidden window.
runHiddenWait(<char>[, <char> dir]) run in hidden window,
wait until complete.
runMaximized(<char>[, <char> dir]) run in maximized window.
runMaximizedWait(<char>[, <char> dir]) run in maximized window.
wait until complete.
runMinimized(<char>[, <char> dir]) run in minimized window.
runMinimizedWait(<char>[, <char> dir]) run in minimized window.
wait until complete.
runWait(<char>[, <char> dir]) run in normal window,
wait until complete.
----------------------------------------------------------------
*/
#define CREATE_NEW_PROCESS_GROUP 0x00000200
#define NORMAL_PRIORITY_CLASS 0x00000020
#define STARTF_USESHOWWINDOW 0x00000001
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define WAIT_NONE 0
#define WAIT_INFINITE 0xFFFFFFFF
#define ZEROS(n) replicate(chr(0), n)
//---------------------------------------------------------------//
// start of constructor.
//---------------------------------------------------------------//
class runProcess
protect x_GetDirectory, x_InitializeExterns, x_ReadDword,;
x_Run, x_WriteDword, x_WriteWord
this.x_InitializeExterns()
//------------------------------------------------------------//
// end of constructor - methods below.
//------------------------------------------------------------//
function close
this.release()
try
close procedure (program(1))
catch(exception e)
endtry
return
//------------------------------------------------------------//
function release
try
release object this
catch(exception e)
endtry
return
//------------------------------------------------------------//
function run(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWNORMAL, false)
//------------------------------------------------------------//
function runHidden(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_HIDE, false)
//------------------------------------------------------------//
function runHiddenWait(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_HIDE, true)
//------------------------------------------------------------//
function runMaximized(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWMAXIMIZED, false)
//------------------------------------------------------------//
function runMaximizedWait(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWMAXIMIZED, true)
//------------------------------------------------------------//
function runMinimized(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWMINIMIZED, false)
//------------------------------------------------------------//
function runMinimizedWait(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWMINIMIZED, true)
//------------------------------------------------------------//
function runWait(cCommand, cFolder)
return this.x_Run(cCommand, cFolder, SW_SHOWNORMAL, true)
//------------------------------------------------------------//
// protected methods below.
//------------------------------------------------------------//
function x_GetDirectory(cValu)
Local cRet
if type("argVector(1)") == "C"
cRet = "" + cValu
else
cRet = set("directory")
endif
return cRet
//------------------------------------------------------------//
function x_InitializeExterns
if not type("RMM_CloseHandle") == "FP"
extern CLOGICAL RMM_CloseHandle(CHANDLE) ;
kernel32 from "CloseHandle"
endif
if not type("RMM_CreateProcess") == "FP"
extern CLOGICAL RMM_CreateProcess( ;
CSTRING, CSTRING, CPTR, CPTR, CLOGICAL,;
CULONG, CPTR, CSTRING, CPTR, CPTR);
kernel32 from "CreateProcessA"
endif
if not type("RMM_GetStartupInfo") == "FP"
extern CVOID RMM_GetStartupInfo(CPTR) ;
kernel32 from "GetStartupInfoA"
endif
if not type("RMM_WaitForSingleObject") == "FP"
extern CULONG RMM_WaitForSingleObject(CHANDLE, CULONG) ;
kernel32 from "WaitForSingleObject"
endif
return
//------------------------------------------------------------//
// return <int> (DWORD = 0 to 4294967295) from a structure.
// a DWORD is the same as a CULONG.
// sBuff = <char> structure.
// nPos = <int> zero-based position in sBuff to begin read.
function x_ReadDword(sBuff, nPos)
return int( ;
sBuff.getByte(nPos) + ;
bitlshift(sBuff.getByte(nPos + 1), 8) + ;
bitlshift(sBuff.getByte(nPos + 2), 16) + ;
bitlshift(sBuff.getByte(nPos + 3), 24))
//------------------------------------------------------------//
function x_Run(cLine, cFolder, nShow, bWait)
Local bRet, cDir, nProc, nThrd, sInfo, sProc
bRet = false
cDir = this.x_GetDirectory(cFolder)
// create a STARTUPINFO structure.
sInfo = ZEROS(34)
// create a PROCESS_INFORMATION structure.
sProc = ZEROS(8)
// assign the size member of the STARTUPINFO.
this.x_WriteDword(sInfo, 0, 68)
// initialize the sInfo structure
// using the current calling process information.
RMM_GetStartupInfo(sInfo)
// set the dwFlags member of the STARTUPINFO structure,
// so that wShowWindow member is enabled.
this.x_WriteDword(sInfo, 44, STARTF_USESHOWWINDOW)
// set the wShowWindow member of the STARTUPINFO structure.
this.x_WriteWord(sInfo, 48, nShow)
if RMM_CreateProcess(null, cLine, null, null, false,;
bitOr(CREATE_NEW_PROCESS_GROUP,;
NORMAL_PRIORITY_CLASS),;
null, cDir, sInfo, sProc)
// the process has been created.
// get the handle to the created process.
nProc = this.x_ReadDword(sProc, 0)
// get the handle to the primary thread
// of the created process.
nThrd = this.x_ReadDword(sProc, 4)
// wait for a signal from the created process.
// if the wait time is 0 (WAIT_NONE), return immediately.
// if the wait time is infinite (WAIT_INFINITE),
// wait until the created process ends.
RMM_WaitForSingleObject(nProc, iif(bWait,;
WAIT_INFINITE, WAIT_NONE))
// close the process (open object) handle (reference).
RMM_CloseHandle(nProc)
// close the thread (open object) handle (reference).
RMM_CloseHandle(nThrd)
// assign success.
bRet := true
endif
return iif(bRet, true, false) // success/fail.
//------------------------------------------------------------//
// write a DWORD into a structure.
// a DWORD is the same as a CULONG.
// sBuff = <char> structure.
// nPos = <int> zero-based position in sBuff to begin write.
// nValu = <int> 0 to 4294967295 for a DWORD.
function x_WriteDword(sBuff, nPos, nValu)
sBuff.setByte(nPos, bitand(nValu, 0xFF))
sBuff.setByte(nPos + 1, bitand(bitzrshift(nValu, 8), 0xFF))
sBuff.setByte(nPos + 2, bitand(bitzrshift(nValu, 16), 0xFF))
sBuff.setByte(nPos + 3, bitand(bitzrshift(nValu, 24), 0xFF))
return
//------------------------------------------------------------//
// write a WORD into a structure.
// a WORD is the same as a CUSHORT.
// sBuff = <char> structure.
// nPos = <int> zero-based position in sBuff to begin write.
// nValu = <int> 0 to 65535 for a WORD.
function x_WriteWord(sBuff, nPos, nValu)
sBuff.setByte(nPos, bitand(nValu, 0xFF))
sBuff.setByte(nPos + 1, bitand(bitzrshift(nValu, 8), 0xFF))
return
endclass
//---------------------------------------------------------------//
// end of class.
//---------------------------------------------------------------//