Function RunShell() Foundation
Starts a command shell or executes a program.
RunShell( <cCmdLine> , ;
[<cProgram>] , ;
[<lAsync>] , ;
[<lBackground>],
[<aStdHandles>|<lInherit>] ) --> xReturn
{nHInput, nHOutput, nHError}
The return value of RunShell() is the return value of the started command shell or program. When a command shell/program is started in asynchronous mode, the return value is always zero. If RunShell() was not able to start <cProgram>, -1 is returned.
The function RunShell() starts a new command shell and passes a character string to it which is executed on the command line. Normally a new window is opened by RunShell() in which the command defined by <cCmdLine> is executed.
At least the parameter <cCmdLine> must be passed to the function RunShell(). At the minimum this can be a null string (""). In this case RunShell() starts the command shell defined as the default command shell in the environment variable OS2_SHELL (OS/2) or COMSPEC (Windows). If <cCmdLine> contains a null string and no command shell can be started, a runtime error occurs.
The parameter <lAsync> determines whether an Xbase++ application is dependent or independent of the newly started command shell or program. When <lAsync> has the logical value .T. (true), the new program is started and the Xbase++ application continues running independent of it. If the value is .F. (false), the Xbase++ application pauses until the newly started program terminates.
The parameter <lBackGround> determines whether the new process is started in the background or in the foreground of the Xbase++ application. By default RunShell() starts new processes in the foreground, meaning they receive input focus and the applicable window is brought to the foreground. If a "Full-Screen" session is started with RunShell(), the function switches automatically to character mode. If the logical value .T. (true) is specified for <lBackGround>, the new process starts in the background of the Xbase++ application which keeps the input focus.
Processes started using RunShell() normally execute completely independent and cannot access resources allocated in the calling process. This behaviour can be overriden via the <aStdHandles> and <lInherit> parameters. If .T. (true) is passed in <lInherit>, the newly started process inherits all inheritable handles from the parent process. These handles correspond to existing operating system objects such as file handles, named pipes or semaphore objects, which have been marked as inheritable. Similarly, the <aStdHandles> parameter can be used to define existing files as the standard I/O devices to be used by the process spawned by RunShell(). This is often used to redirect the output of the process to a file and is demonstrated in an example below.
VIEW Cmdref Start and VIEW Cmdref Cmd
HELP Cmd and START /?
HELP Command and START /?
// The example demonstrates various calls of RunShell().
// Pay attention to "/C" for passing parameters to a newly started
// command shell.
PROCEDURE Main
// Open a new DOS session with window title
? RunShell( '/C START "Xbase++ DOS Session"' )
// List current directory to file
? RunShell( "/C DIR /f > dir.txt" )
// Direct call of the Windows program NOTEPAD.EXE including
// command line parameter. Asynchronous execution (.T.)
// Note: Notepad.exe can be found using PATH.
? RunShell( "dir.txt", "NOTEPAD.EXE", .T. )
// Indirect call of the Windows program EXPLORER.EXE
// using the START command.
// The explorer displays the current directory
? RunShell( "/C START EXPLORER.EXE ." )
// Direct call of the Windows program Wordpad and passing the name of
// an existing document
// Note: Wordpad.exe must have the full path included, and the program
// name must not be quoted. Codepage specific characters must be converted
// to their original code if necessary (ConvToAnsiCp()).
? RunShell( "hello.doc", "C:\Program Files\Windows NT\Accessories\Wordpad.exe" )
// Call Wordpad and passing command line parameters that must be quoted.
? RunShell( '"C:\My Files\hello.doc"', "C:\Program Files\Windows NT\Accessories\Wordpad.exe" )
RETURN
// The example demonstrates how files created by the
// parent process can be set as the standard output
// devices of a process started with RunShell().
// After the new process has exited, the redirected
// output could be analyzed by processing the
// file contents on disk.
#include "fileio.ch"
#define CRLF Chr(13)+Chr(10)
#define STDOUT_FILE "stdout.txt"
#define STDERR_FILE "stderr.txt"
//
// The application assumes the roles of both
// the parent and the child process depending
// on whether a parameter is passed.
//
PROCEDURE Main()
IF PCount() == 0
ParentProcessMain()
ELSE
ChildProcessMain()
ENDIF
RETURN
PROCEDURE ParentProcessMain()
LOCAL nHStdOut, nHStdErr, aStdHandles
LOCAL nAttribute
// The files we are creating will be read/write and
// deleted after the file handle is closed. The file
// handles can be inherited by the new process.
nAttribute := FC_NORMAL+FC_AUTODELETE+FA_INHERITABLE
nHStdOut := FCreate( STDOUT_FILE, nAttribute )
nHStdErr := FCreate( STDERR_FILE, nAttribute )
// The files created become the standard output
// devices of the new process
aStdHandles := {NIL,nHStdOut,nHStdErr}
// Start the same application again with a parameter.
// Start RunShell() so that it does not return until
// the child process is terminated.
RunShell( "param", AppName(.F.), .F., ,aStdHandles )
// Print what the child process has written to the
// output devices
? "Print nHStdOut"
PrintFile( nHStdOut )
? "Print nHStdErr"
PrintFile( nHStdErr )
// Close and delete the files
FClose( nHStdOut )
FClose( nHStdErr )
RETURN
// The child process prints to the standard output
// and standard error device.
PROCEDURE ChildProcessMain()
OutStd( "Output to STDOUT" )
OutErr( "Output to STDERR" )
RETURN
// Print the contents of a file
PROCEDURE PrintFile( nH )
LOCAL cBuffer
FSeek( nH, 0, FS_SET )
cBuffer := Space( FSize( nH ) )
FRead( nH, @cBuffer, Len(cBuffer) )
? cBuffer
RETURN
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.