\membersection{::wxExecute}\label{wxexecute}
-\func{long}{wxExecute}{\param{const wxString\& }{command}, \param{bool }{sync = FALSE}, \param{wxProcess *}{callback = NULL}}
+\func{long}{wxExecute}{\param{const wxString\& }{command}, \param{int }{sync = wxEXEC\_ASYNC}, \param{wxProcess *}{callback = NULL}}
-\func{long}{wxExecute}{\param{char **}{argv}, \param{bool }{sync = FALSE}, \param{wxProcess *}{callback = NULL}}
+\func{long}{wxExecute}{\param{char **}{argv}, \param{int }{flags = wxEXEC\_ASYNC}, \param{wxProcess *}{callback = NULL}}
\func{long}{wxExecute}{\param{const wxString\& }{command}, \param{wxArrayString\& }{output}}
The semantics of the third and fourth versions is different from the first two
and is described in more details below.
-If {\it sync} is FALSE (the default), flow of control immediately returns.
-If TRUE, the current application waits until the other program has terminated.
+If {\it flags} parameter contains {\tt wxEXEC\_ASYNC} flag (the default), flow
+of control immediately returns. If it contains {\tt wxEXEC\_SYNC}, the current
+application waits until the other program has terminated.
In the case of synchronous execution, the return value is the exit code of
the process (which terminates by the moment the function returns) and will be
and only this, case the calling code will not get the notification about
process termination.
-If callback isn't NULL and if execution is asynchronous (note that callback
-parameter can not be non-NULL for synchronous execution),
+If callback isn't NULL and if execution is asynchronous,
\helpref{wxProcess::OnTerminate}{wxprocessonterminate} will be called when
-the process finishes.
+the process finishes. Specifying this parameter also allows you to redirect the
+standard input and/or output of the process being launched by calling
+\helpref{Redirect}{wxprocessredirect}. If the child process IO is redirected,
+under Windows the process window is not shown by default (this avoids having to
+flush an unnecessary console for the processes which don't create any windows
+anyhow) but a {\tt wxEXEC\_NOHIDE} flag can be used to prevent this from
+happening, i.e. with this flag the child process window will be shown normally.
Finally, you may use the third overloaded version of this function to execute
a process (always synchronously) and capture its output in the array
See also \helpref{wxShell}{wxshell}, \helpref{wxProcess}{wxprocess},
\helpref{Exec sample}{sampleexec}.
+\wxheading{Parameters}
+
+\docparam{command}{The command to execute and any parameters to pass to it as a
+single string.}
+
+\docparam{argv}{The command to execute should be the first element of this
+array, any additional ones are the command parameters and the array must be
+terminated with a NULL pointer.}
+
+\docparam{flags}{Combination of bit masks {\tt wxEXEC\_ASYNC},
+{\tt wxEXEC\_SYNC} and {\tt wxEXEC\_NOHIDE}}
+
+\docparam{callback}{An optional pointer to \helpref{wxProcess}{wxprocess}}
+
\wxheading{Include files}
<wx/utils.h>
// Process management
// ----------------------------------------------------------------------------
-// Execute another program. Returns 0 if there was an error, a PID otherwise.
-WXDLLEXPORT long wxExecute(wxChar **argv, bool sync = FALSE,
+// NB: for backwars compatibility reasons the values of wxEXEC_[A]SYNC *must*
+// be 0 and 1, don't change!
+
+enum
+{
+ wxEXEC_ASYNC = 0, // execute the process asynchronously
+ wxEXEC_SYNC = 1, // synchronously
+ wxEXEC_NOHIDE = 2 // under Windows, don't hide the child even if it's
+ // IO is redirected (this is done by default)
+};
+
+// Execute another program.
+//
+// If flags contain wxEXEC_SYNC, return -1 on failure and the exit code of the
+// process if everything was ok. Otherwise (i.e. if wxEXEC_ASYNC), return 0 on
+// failure and the PID of the launched process if ok.
+WXDLLEXPORT long wxExecute(wxChar **argv, int flags = wxEXEC_ASYNC,
wxProcess *process = (wxProcess *) NULL);
-WXDLLEXPORT long wxExecute(const wxString& command, bool sync = FALSE,
+WXDLLEXPORT long wxExecute(const wxString& command, int flags = wxEXEC_ASYNC,
wxProcess *process = (wxProcess *) NULL);
-// execute the command capturing its output into an array line by line
+// execute the command capturing its output into an array line by line, this is
+// always synchronous
WXDLLEXPORT long wxExecute(const wxString& command,
wxArrayString& output);
-// also capture stderr
+// also capture stderr (also synchronous)
WXDLLEXPORT long wxExecute(const wxString& command,
wxArrayString& output,
wxArrayString& error);
#endif // wxUSE_IPC
-long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
+long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
{
wxCHECK_MSG( !!cmd, 0, wxT("empty command in wxExecute") );
// termination, try to execute DDE command right now, it can succeed if
// the process is already running - but as it fails if it's not
// running, suppress any errors it might generate
- if ( !sync )
+ if ( !(flags & wxEXEC_SYNC) )
{
wxLogNull noErrors;
if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCommand) )
{
wxLogSysError(_("Can't create the inter-process read pipe"));
- // indicate failure in both cases
- return sync ? -1 : 0;
+ // indicate failure: we need to return different error code
+ // depending on the sync flag
+ return flags & wxEXEC_SYNC ? -1 : 0;
}
// and a stdout one
wxLogSysError(_("Can't create the inter-process write pipe"));
- return sync ? -1 : 0;
+ return flags & wxEXEC_SYNC ? -1 : 0;
}
(void)::CreatePipe(&hpipeStderr[0], &hpipeStderr[1], &security, 0);
#if wxUSE_STREAMS
if ( redirect )
{
- // when the std IO is redirected, we don't show the (console) process
- // window
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hpipeStdin[0];
si.hStdOutput = hpipeStdout[1];
si.hStdError = hpipeStderr[1];
- si.wShowWindow = SW_HIDE;
+ // when the std IO is redirected, we don't show the (console) process
+ // window by default, but this can be overridden by the caller by
+ // specifying wxEXEC_NOHIDE flag
+ if ( !(flags & wxEXEC_NOHIDE) )
+ {
+ si.dwFlags |= STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+ }
// we must duplicate the handle to the write side of stdin pipe to make
// it non inheritable: indeed, we must close hpipeStdin[1] before
wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
- return sync ? -1 : 0;
+ return flags & wxEXEC_SYNC ? -1 : 0;
}
#if wxUSE_STREAMS
data->hProcess = pi.hProcess;
data->dwProcessId = pi.dwProcessId;
data->hWnd = hwnd;
- data->state = sync;
- if ( sync )
+ data->state = (flags & wxEXEC_SYNC) != 0;
+ if ( flags & wxEXEC_SYNC )
{
// handler may be !NULL for capturing program output, but we don't use
// it wxExecuteData struct in this case
}
#endif // wxUSE_IPC
- if ( !sync )
+ if ( !(flags & wxEXEC_SYNC) )
{
// clean up will be done when the process terminates
return dwExitCode;
#else // Win16
long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
- if (instanceID < 32) return(0);
+ if (instanceID < 32)
+ return flags & wxEXEC_SYNC ? -1 : 0;
- if (sync) {
+ if ( flags & wxEXEC_SYNC )
+ {
int running;
- do {
+ do
+ {
wxYield();
running = GetModuleUsage((HINSTANCE)instanceID);
} while (running);
}
- return(instanceID);
+ return instanceID;
#endif // Win16/32
}
-long wxExecute(char **argv, bool sync, wxProcess *handler)
+long wxExecute(char **argv, int flags, wxProcess *handler)
{
wxString command;
command.RemoveLast();
- return wxExecute(command, sync, handler);
+ return wxExecute(command, flags, handler);
}
#define WXEXECUTE_NARGS 127
-long wxExecute( const wxString& command, bool sync, wxProcess *process )
+long wxExecute( const wxString& command, int flags, wxProcess *process )
{
wxCHECK_MSG( !command.IsEmpty(), 0, wxT("can't exec empty command") );
argv[argc] = NULL;
// do execute the command
- long lRc = wxExecute(argv, sync, process);
+ long lRc = wxExecute(argv, flags, process);
// clean up
argc = 0;
bool wxShell(const wxString& command)
{
- return wxExecute(wxMakeShellCommand(command), TRUE /* sync */) == 0;
+ return wxExecute(wxMakeShellCommand(command), wxEXEC_SYNC) == 0;
}
bool wxShell(const wxString& command, wxArrayString& output)
#endif // wxUSE_STREAMS
long wxExecute(wxChar **argv,
- bool sync,
+ int flags,
wxProcess *process)
{
// for the sync execution, we return -1 to indicate failure, but for async
//
// we define this as a macro, not a variable, to avoid compiler warnings
// about "ERROR_RETURN_CODE value may be clobbered by fork()"
- #define ERROR_RETURN_CODE ((sync) ? -1 : 0)
+ #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0)
wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") );
// input/output which might block the process or irritate the user. If
// one wants proper IO for the subprocess, the right thing to do is to
// start an xterm executing it.
- if ( !sync )
+ if ( !(flags & wxEXEC_SYNC) )
{
for ( int fd = 0; fd < FD_SETSIZE; fd++ )
{
#if wxUSE_GUI && !defined(__WXMICROWIN__)
wxEndProcessData *data = new wxEndProcessData;
- if ( sync )
+ if ( flags & wxEXEC_SYNC )
{
// we may have process for capturing the program output, but it's
// not used in wxEndProcessData in the case of sync execution
return pid;
}
#else // !wxUSE_GUI
- wxASSERT_MSG( sync, wxT("async execution not supported yet") );
+
+ wxASSERT_MSG( flags & wxEXEC_SYNC,
+ wxT("async execution not supported yet") );
int exitcode = 0;
if ( waitpid(pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) )