Você está na página 1de 7

re are various ways to run another program from within your own.

Most of the good ones are


compiler dependant, so best research your help files before going too far

In all the example code below you'll find some sample output. In the cases where a child
program has been invoked, this source was used to make that child:

#include <stdio.h>

int main(int argc, char *argv[] )


{
int i = 0;
printf("I am the child\n");
while (--argc)
printf ("Arg %d %s\n", ++i, *++argv);
return 0;
}

Now, we'll start with a simple example of system().

OPTION 1 - system()

Prototype:
int system (const char * s);

This function executes a command specified in s, and returns after the command has been
completed. A few reasons not to use this method are:

 The child program is uninterruptible from the parent program. This means that you cannot
stop the program you have started. If it takes 5 hours to complete, that's how long your program
will wait
 You cannot communicate or share variables with the child process
 For various security reasons, its unsafe and may leave your system open to exploitation.
 In system terms, its relatively slow.

Having said that, it is easy to use, and these things have their place. Here is a example of how to
use it.

/*
* This example assumes the program you want to execute
* is called child.exe, and resides in the same
* directory as this program
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
char child1[] = "child.exe";
char child2[BUFSIZ];

/*
* Execute by passing the name directly
*/
system ("child.exe");

/*
* Execute by passing an array name
*/
system (child1);

/*
* Build a buffer, and execute the commands within it
*/
strcpy (child2, "child.exe");
strcat (child2, " -aparm -b");

printf ("Executing %s\n", child2);


system (child2);

return 0;
}

/*
* Program output:
I am the child
I am the child
Executing child.exe -aparm -b
I am the child
Arg 1 -aparm
Arg 2 -b
*
*/

OPTION 2 - spawn

There a family of functions collectively known as spawn. These are:

#include <process.h>
int spawnl( mode, path, arg0, arg1..., argn,
NULL );
int spawnle( mode, path, arg0, arg1..., argn,
NULL, envp);
int spawnlp( mode, file, arg0, arg1..., argn,
NULL );
int spawnlpe( mode, file, arg0, arg1..., argn,
NULL, envp);
int spawnv( mode, path, argv );
int spawnve( mode, path, argv, envp );
int spawnvp( mode, file, argv );
int spawnvpe( mode, file, argv, envp );
int mode; /* mode for parent */
const char *path; /* file name incl. path */
const char *file; /* file name */
const char *arg0,...,
*argn; /* arguments */
char *const argv[]; /* array of arguments */
char *const envp[]; /* environment strings */

These functions create and execute a new child process, named by path or file (depending on the
form of the function used). The value of mode determines how the program is loaded, and how
the parent program will behave after the child program is initiated.

P_WAIT
The child program is loaded into memory and executed, and then the parent program resumes
execution.
P_NOWAIT
Causes the parent program to execute concurrently with the new child process.
P_NOWAITO
Causes the parent program to execute concurrently with the new child process. The wait()
function cannot be used to obtain the exit code.
P_OVERLAY
The child program replaces the parent program in memory and is executed. No return is made to
the parent program.

The various forms of the spawn functions are:

 The l form : These contain an argument list, terminated by a NULL pointer. The argument
arg0 should point to a filename that is associated with the child program.
 The v form : These contain a pointer to an argument vector. The value in argv[0] should
point to a filename that is associated with the child program. The last member of argv must be a
NULL pointer. The value of argv cannot be NULL, but argv[0] can be a NULL pointer if no
argument strings are passed.
 The p form : These use paths listed in the PATH environment variable to locate the program
to be loaded, provided certain conditions are met.
 The e form : These pass a pointer to a new environment for the child program. The argument
envp is an array of character pointers to null-terminated strings. The array of pointers is
terminated by a NULL pointer. The value of envp cannot be NULL, but envp[0] can be a NULL
pointer, if no environment strings are passed.
#include <stdio.h>
#include <process.h>

int main(void)
{

puts("Spawning child with spawnl");

spawnl( P_WAIT, "child.exe",


"child.exe", "Using spawnl", "Arg1", "Arg2", NULL );

return 0;
}

/*
* Program output:
Spawning child with spawnl
I am the child
Arg 1 Using
Arg 2 spawnl
Arg 3 Arg1
Arg 4 Arg2
*
*/

#include <stdio.h>
#include <process.h>

int main(void)
{
char *my_args[4];

my_args[0] = "child.exe";
my_args[1] = "arg1";
my_args[2] = "arg2";
my_args[3] = NULL;

puts("Spawning child with spawnv");

spawnv( P_WAIT, "child.exe", my_args);

return 0;
}

/*
* Program output:
Spawning child with spawnv
I am the child
Arg 1 arg1
Arg 2 arg2
*
*/

OPTION 3 - fork/exec

Using a combination of fork and exec, you can duplicate your running program in memory, then
turn the second copy into another program altogether.

Prototypes:
#include <sys/types.h>
#include <unistd.h>
pid_t fork( void );

The exec family consists of:

#include <unistd.h>
int execl( path, arg0, arg1..., argn, NULL );
int execle( path, arg0, arg1..., argn, NULL,
envp );
int execlp( file, arg0, arg1..., argn, NULL );
int execlpe( file, arg0, arg1..., argn, NULL,
envp );
int execv( path, argv );
int execve( path, argv, envp );
int execvp( file, argv );
int execvpe( file, argv, envp );

const char *path; /* file name incl. path */


const char *file; /* file name */
const char *arg0,...,
*argn; /* arguments */
char *const argv[]; /* array of arguments */
char *const envp[]; /* environment strings */

These have the same forms to the spawn functions (l, v, p and e).
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
char *my_args[5];
pid_t pid;

my_args[0] = "child.exe";
my_args[1] = "arg1";
my_args[2] = "arg2";
my_args[3] = NULL;

puts ("fork()ing");

switch ((pid = fork()))


{
case -1:
/* Fork() has failed */
perror ("fork");
break;
case 0:
/* This is processed by the child */
execv ("child.exe", my_args);
puts("Uh oh! If this prints, execv() must have failed");
exit(EXIT_FAILURE);
break;
default:
/* This is processed by the parent */
puts ("This is a message from the parent");
break;
}

puts ("End of parent program");


return 0;
}

/*
* Program output:
fork()ing
This is a message from the parent
End of parent program
I am the child
Arg 1 arg1
Arg 2 arg2
*
*/

Further options

Windows options: (Credit: Sunlight) Use one of the _spawn functions, or CreateProcess, or
ShellExecute. Which one you use depends on what you want to do. _spawn is simplest (and most
portable), CreateProcess gives you the most control, ShellExecute gives you the most flexibility
(starts documents as well as files, for example).

Here are some examples of Windows versions, compliments of Fordy.

Using CreateProcess()

#include <windows.h>

int main(void)
{
char szPath[] = "C:\\WINDOWS\\system32\\Calc.exe";
PROCESS_INFORMATION pif; //Gives info on the thread and..
//..process for the new process
STARTUPINFO si; //Defines how to start the program

ZeroMemory(&si,sizeof(si)); //Zero the STARTUPINFO struct


si.cb = sizeof(si); //Must set size of structure

BOOL bRet = CreateProcess(


szPath, //Path to executable file
NULL, //Command string - not needed here
NULL, //Process handle not inherited
NULL, //Thread handle not inherited
FALSE, //No inheritance of handles
0, //No special flags
NULL, //Same environment block as this prog
NULL, //Current directory - no separate path
&si, //Pointer to STARTUPINFO
&pif); //Pointer to PROCESS_INFORMATION

if(bRet == FALSE)
{
MessageBox(HWND_DESKTOP,"Unable to start program","",MB_OK);
return 1;
}

CloseHandle(pif.hProcess); //Close handle to process


CloseHandle(pif.hThread); //Close handle to thread

return 0;
}

Using ShellExecute()
#include <windows.h> //You need shell32.lib for this one

int main(void)
{
char szPath[] = "C:\\WINDOWS\\system32\\Calc.exe";

HINSTANCE hRet = ShellExecute(


HWND_DESKTOP, //Parent window
"open", //Operation to perform
szPath, //Path to program
NULL, //Parameters
NULL, //Default directory
SW_SHOW); //How to open

/*
The function returns a HINSTANCE (not really useful in this case)
So therefore, to test its result, we cast it to a LONG.
Any value over 32 represents success!
*/

if((LONG)hRet <= 32)


{
MessageBox(HWND_DESKTOP,"Unable to start program","",MB_OK);
return 1;
}

return 0;
}

Você também pode gostar