added wxEXEC_NOHIDE flag, modified wxExecute() to take a combination of bit flags instead of a boolean parameter
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14738 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
7841e80fa1
commit
fbf456aa89
@ -424,9 +424,9 @@ processes.
|
||||
|
||||
\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}}
|
||||
|
||||
@ -450,8 +450,9 @@ arguments, terminated by NULL.
|
||||
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
|
||||
@ -469,10 +470,15 @@ case of using DDE under Windows for command execution). In particular, in this,
|
||||
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
|
||||
@ -482,6 +488,20 @@ the messages from standard error output in the {\it errors} 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>
|
||||
|
@ -148,17 +148,33 @@ WXDLLEXPORT wxString wxDecToHex(int dec);
|
||||
// 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);
|
||||
|
@ -360,7 +360,7 @@ static bool wxExecuteDDE(const wxString& ddeServer,
|
||||
|
||||
#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") );
|
||||
|
||||
@ -439,7 +439,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
// 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) )
|
||||
@ -484,8 +484,9 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
{
|
||||
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
|
||||
@ -496,7 +497,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
|
||||
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);
|
||||
@ -513,15 +514,20 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
#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
|
||||
@ -587,7 +593,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
|
||||
wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
|
||||
|
||||
return sync ? -1 : 0;
|
||||
return flags & wxEXEC_SYNC ? -1 : 0;
|
||||
}
|
||||
|
||||
#if wxUSE_STREAMS
|
||||
@ -632,8 +638,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
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
|
||||
@ -712,7 +718,7 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
}
|
||||
#endif // wxUSE_IPC
|
||||
|
||||
if ( !sync )
|
||||
if ( !(flags & wxEXEC_SYNC) )
|
||||
{
|
||||
// clean up will be done when the process terminates
|
||||
|
||||
@ -742,21 +748,24 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
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;
|
||||
|
||||
@ -767,6 +776,6 @@ long wxExecute(char **argv, bool sync, wxProcess *handler)
|
||||
|
||||
command.RemoveLast();
|
||||
|
||||
return wxExecute(command, sync, handler);
|
||||
return wxExecute(command, flags, handler);
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ int wxKill(long pid, wxSignal sig, wxKillError *rc)
|
||||
|
||||
#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") );
|
||||
|
||||
@ -247,7 +247,7 @@ long wxExecute( const wxString& command, bool sync, wxProcess *process )
|
||||
argv[argc] = NULL;
|
||||
|
||||
// do execute the command
|
||||
long lRc = wxExecute(argv, sync, process);
|
||||
long lRc = wxExecute(argv, flags, process);
|
||||
|
||||
// clean up
|
||||
argc = 0;
|
||||
@ -280,7 +280,7 @@ static wxString wxMakeShellCommand(const wxString& command)
|
||||
|
||||
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)
|
||||
@ -519,7 +519,7 @@ wxStreamTempBuffer::~wxStreamTempBuffer()
|
||||
#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
|
||||
@ -527,7 +527,7 @@ long wxExecute(wxChar **argv,
|
||||
//
|
||||
// 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") );
|
||||
|
||||
@ -632,7 +632,7 @@ long wxExecute(wxChar **argv,
|
||||
// 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++ )
|
||||
{
|
||||
@ -710,7 +710,7 @@ long wxExecute(wxChar **argv,
|
||||
#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
|
||||
@ -759,7 +759,9 @@ long wxExecute(wxChar **argv,
|
||||
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) )
|
||||
|
Loading…
Reference in New Issue
Block a user