Add wxEXEC_HIDE_CONSOLE flag allowing to unconditionally do it under MSW.

Also renamed wxEXEC_NOHIDE to wxEXEC_SHOW_CONSOLE for symmetry (keeping the
old name for compatibility, of course).

Extend exec sample to allow easily testing the different flags and adding more
of them later.

See #13676.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69964 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2011-12-08 20:22:55 +00:00
parent 0266103273
commit 4fe4a7c50f
5 changed files with 74 additions and 45 deletions

View File

@ -465,6 +465,7 @@ All:
wxGetUTCTimeMillis() returning what this function used to return.
- Added wxCriticalSection::TryEnter() (Catalin Raceanu).
- Add support for OpenBSD to wxDialUpManager (brad0).
- Added wxEXEC_HIDE_CONSOLE flag.
All (GUI):

View File

@ -334,7 +334,11 @@ enum
// under Windows, don't hide the child even if it's IO is redirected (this
// is done by default)
wxEXEC_NOHIDE = 2,
wxEXEC_SHOW_CONSOLE = 2,
// deprecated synonym for wxEXEC_SHOW_CONSOLE, use the new name as it's
// more clear
wxEXEC_NOHIDE = wxEXEC_SHOW_CONSOLE,
// under Unix, if the process is the group leader then passing wxKILL_CHILDREN to wxKill
// kills all children as well as pid
@ -350,6 +354,10 @@ enum
// until the child process finishes
wxEXEC_NOEVENTS = 16,
// under Windows, hide the console of the child process if it has one, even
// if its IO is not redirected
wxEXEC_HIDE_CONSOLE = 32,
// convenient synonym for flags given system()-like behaviour
wxEXEC_BLOCK = wxEXEC_SYNC | wxEXEC_NOEVENTS
};

View File

@ -875,6 +875,16 @@ enum
*/
wxEXEC_NOEVENTS = 16,
/**
Hide child process console under MSW.
Under MSW, hide the console of the child process if it has one,
even if its IO is not redirected.
This flag is ignored under the other platforms.
*/
wxEXEC_HIDE_CONSOLE = 32,
/**
Convenient synonym for flags given system()-like behaviour.
*/
@ -911,12 +921,15 @@ enum
wxProcess::OnTerminate() will be called when the process finishes.
Specifying this parameter also allows you to redirect the standard input
and/or output of the process being launched by calling
wxProcess::Redirect(). 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 @c wxEXEC_NOHIDE flag can be used to prevent this from
happening, i.e. with this flag the child process window will be shown
normally.
wxProcess::Redirect().
Under Windows, when launching a console process its console is shown by
default but hidden if its IO is redirected. Both of these default
behaviours may be overridden: if ::wxEXEC_HIDE_CONSOLE is specified, the
console will never be shown. If ::wxEXEC_SHOW_CONSOLE is used, the console
will be shown even if the child process IO is redirected. Neither of these
flags affect non-console Windows applications or does anything under the
other systems.
Under Unix the flag @c wxEXEC_MAKE_GROUP_LEADER may be used to ensure that
the new process is a group leader (this will create a new session if
@ -940,9 +953,9 @@ enum
string, i.e. "emacs file.txt".
@param flags
Must include either wxEXEC_ASYNC or wxEXEC_SYNC and can also include
wxEXEC_NOHIDE, wxEXEC_MAKE_GROUP_LEADER (in either case) or
wxEXEC_NODISABLE and wxEXEC_NOEVENTS or wxEXEC_BLOCK, which is equal to
their combination, in wxEXEC_SYNC case.
wxEXEC_SHOW_CONSOLE, wxEXEC_HIDE_CONSOLE, wxEXEC_MAKE_GROUP_LEADER (in
either case) or wxEXEC_NODISABLE and wxEXEC_NOEVENTS or wxEXEC_BLOCK,
which is equal to their combination, in wxEXEC_SYNC case.
@param callback
An optional pointer to wxProcess.
@param env

View File

@ -108,7 +108,6 @@ public:
void OnEndBusyCursor(wxCommandEvent& event);
void OnSyncExec(wxCommandEvent& event);
void OnSyncNoEventsExec(wxCommandEvent& event);
void OnAsyncExec(wxCommandEvent& event);
void OnShell(wxCommandEvent& event);
void OnExecWithRedirect(wxCommandEvent& event);
@ -141,6 +140,8 @@ private:
const wxArrayString& output,
const wxString& title);
int GetExecFlags() const;
void DoAsyncExec(const wxString& cmd);
void AddAsyncProcess(MyProcess *process) { m_allAsync.push_back(process); }
@ -313,7 +314,6 @@ enum
Exec_BeginBusyCursor,
Exec_EndBusyCursor,
Exec_SyncExec = 200,
Exec_SyncNoEventsExec,
Exec_AsyncExec,
Exec_Shell,
Exec_POpen,
@ -324,6 +324,9 @@ enum
Exec_DDERequest,
Exec_Redirect,
Exec_Pipe,
Exec_Flags_HideConsole,
Exec_Flags_ShowConsole,
Exec_Flags_NoEvents,
Exec_About = wxID_ABOUT,
// control ids
@ -350,7 +353,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Exec_EndBusyCursor, MyFrame::OnEndBusyCursor)
EVT_MENU(Exec_SyncExec, MyFrame::OnSyncExec)
EVT_MENU(Exec_SyncNoEventsExec, MyFrame::OnSyncNoEventsExec)
EVT_MENU(Exec_AsyncExec, MyFrame::OnAsyncExec)
EVT_MENU(Exec_Shell, MyFrame::OnShell)
EVT_MENU(Exec_Redirect, MyFrame::OnExecWithRedirect)
@ -457,11 +459,17 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
menuFile->AppendSeparator();
menuFile->Append(Exec_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
wxMenu *flagsMenu = new wxMenu;
flagsMenu->AppendCheckItem(Exec_Flags_HideConsole, "Always &hide console");
flagsMenu->AppendCheckItem(Exec_Flags_ShowConsole, "Always &show console");
flagsMenu->AppendCheckItem(Exec_Flags_NoEvents, "Disable &events",
"This flag is valid for sync execution only");
wxMenu *execMenu = new wxMenu;
execMenu->AppendSubMenu(flagsMenu, "Execution flags");
execMenu->AppendSeparator();
execMenu->Append(Exec_SyncExec, wxT("Sync &execution...\tCtrl-E"),
wxT("Launch a program and return when it terminates"));
execMenu->Append(Exec_SyncNoEventsExec, wxT("Sync execution and &block...\tCtrl-B"),
wxT("Launch a program and block until it terminates"));
execMenu->Append(Exec_AsyncExec, wxT("&Async execution...\tCtrl-A"),
wxT("Launch a program and return immediately"));
execMenu->Append(Exec_Shell, wxT("Execute &shell command...\tCtrl-S"),
@ -812,10 +820,26 @@ static bool QueryExec(wxString& cmd, wxExecuteEnv& env)
// event handlers: exec menu
// ----------------------------------------------------------------------------
int MyFrame::GetExecFlags() const
{
wxMenuBar* const mbar = GetMenuBar();
int flags = 0;
if ( mbar->IsChecked(Exec_Flags_HideConsole) )
flags |= wxEXEC_HIDE_CONSOLE;
if ( mbar->IsChecked(Exec_Flags_ShowConsole) )
flags |= wxEXEC_SHOW_CONSOLE;
if ( mbar->IsChecked(Exec_Flags_NoEvents) )
flags |= wxEXEC_NOEVENTS;
return flags;
}
void MyFrame::DoAsyncExec(const wxString& cmd)
{
MyProcess * const process = new MyProcess(this, cmd);
m_pidLast = wxExecute(cmd, wxEXEC_ASYNC, process);
m_pidLast = wxExecute(cmd, wxEXEC_ASYNC | GetExecFlags(), process);
if ( !m_pidLast )
{
wxLogError(wxT("Execution of '%s' failed."), cmd.c_str());
@ -843,26 +867,7 @@ void MyFrame::OnSyncExec(wxCommandEvent& WXUNUSED(event))
wxLogStatus( wxT("'%s' is running please wait..."), cmd.c_str() );
int code = wxExecute(cmd, wxEXEC_SYNC, NULL, &env);
wxLogStatus(wxT("Process '%s' terminated with exit code %d."),
cmd.c_str(), code);
m_cmdLast = cmd;
}
void MyFrame::OnSyncNoEventsExec(wxCommandEvent& WXUNUSED(event))
{
wxString cmd = wxGetTextFromUser(wxT("Enter the command: "),
DIALOG_TITLE,
m_cmdLast);
if ( !cmd )
return;
wxLogStatus( wxT("'%s' is running please wait..."), cmd.c_str() );
int code = wxExecute(cmd, wxEXEC_BLOCK);
int code = wxExecute(cmd, wxEXEC_SYNC | GetExecFlags(), NULL, &env);
wxLogStatus(wxT("Process '%s' terminated with exit code %d."),
cmd.c_str(), code);

View File

@ -755,15 +755,6 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
si.hStdOutput = pipeOut[wxPipe::Write];
si.hStdError = pipeErr[wxPipe::Write];
// 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 the writing end of pipeIn
// before launching the child process as otherwise this handle will be
@ -788,6 +779,17 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
}
#endif // wxUSE_STREAMS
// The default logic for showing the console is to show it only if the IO
// is not redirected however wxEXEC_{SHOW,HIDE}_CONSOLE flags can be
// explicitly specified to change it.
if ( (flags & wxEXEC_HIDE_CONSOLE) ||
(redirect && !(flags & wxEXEC_SHOW_CONSOLE)) )
{
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
}
PROCESS_INFORMATION pi;
DWORD dwFlags = CREATE_SUSPENDED;