1. improved wxKill() implementation for Win32

2. added wxKillError output parameter to wxKill
3. added wxProcess::Kill() and Exists()
4. documented all the new stuff
5. updated the sample to show it


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10592 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2001-06-16 00:59:07 +00:00
parent b3d008dbd5
commit 50567b69d6
9 changed files with 545 additions and 67 deletions

View File

@@ -40,6 +40,7 @@
#include "wx/textdlg.h"
#include "wx/listbox.h"
#include "wx/filedlg.h"
#include "wx/choicdlg.h"
#endif
#include "wx/txtstrm.h"
@@ -83,6 +84,8 @@ public:
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnKill(wxCommandEvent& event);
void OnClear(wxCommandEvent& event);
void OnSyncExec(wxCommandEvent& event);
@@ -109,6 +112,9 @@ private:
void DoAsyncExec(const wxString& cmd);
// the PID of the last process we launched asynchronously
int m_pidLast;
// last command we executed
wxString m_cmdLast;
@@ -192,6 +198,7 @@ enum
{
// menu items
Exec_Quit = 100,
Exec_Kill,
Exec_ClearLog,
Exec_SyncExec = 200,
Exec_AsyncExec,
@@ -215,6 +222,7 @@ static const wxChar *DIALOG_TITLE = _T("Exec sample");
// simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Exec_Quit, MyFrame::OnQuit)
EVT_MENU(Exec_Kill, MyFrame::OnKill)
EVT_MENU(Exec_ClearLog, MyFrame::OnClear)
EVT_MENU(Exec_SyncExec, MyFrame::OnSyncExec)
@@ -273,6 +281,8 @@ bool MyApp::OnInit()
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
m_pidLast = 0;
#ifdef __WXMAC__
// we need this in order to allow the about menu relocation, since ABOUT is
// not the default id of the about menu
@@ -281,6 +291,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
// create a menu bar
wxMenu *menuFile = new wxMenu(_T(""), wxMENU_TEAROFF);
menuFile->Append(Exec_Kill, _T("&Kill process...\tCtrl-K"),
_T("Kill a process by PID"));
menuFile->AppendSeparator();
menuFile->Append(Exec_ClearLog, _T("&Clear log\tCtrl-C"),
_T("Clear the log window"));
menuFile->AppendSeparator();
@@ -334,8 +347,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
#endif // wxUSE_STATUSBAR
}
// event handlers
// ----------------------------------------------------------------------------
// event handlers: file and help menu
// ----------------------------------------------------------------------------
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
@@ -350,15 +364,117 @@ void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event))
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("Exec sample\n<EFBFBD> 2000 Vadim Zeitlin"),
wxMessageBox(_T("Exec wxWindows Sample\n<EFBFBD> 2000-2001 Vadim Zeitlin"),
_T("About Exec"), wxOK | wxICON_INFORMATION, this);
}
void MyFrame::OnKill(wxCommandEvent& WXUNUSED(event))
{
long pid = wxGetNumberFromUser(_T("Please specify the process to kill"),
_T("Enter PID:"),
_T("Exec question"),
m_pidLast,
1, INT_MAX,
this);
if ( pid == -1 )
{
// cancelled
return;
}
static const wxString signalNames[] =
{
_T("Just test (SIGNONE)"),
_T("Hangup (SIGHUP)"),
_T("Interrupt (SIGINT)"),
_T("Quit (SIGQUIT)"),
_T("Illegal instruction (SIGILL)"),
_T("Trap (SIGTRAP)"),
_T("Abort (SIGABRT)"),
_T("Emulated trap (SIGEMT)"),
_T("FP exception (SIGFPE)"),
_T("Kill (SIGKILL)"),
_T("Bus (SIGBUS)"),
_T("Segment violation (SIGSEGV)"),
_T("System (SIGSYS)"),
_T("Broken pipe (SIGPIPE)"),
_T("Alarm (SIGALRM)"),
_T("Terminate (SIGTERM)"),
};
int sig = wxGetSingleChoiceIndex(_T("How to kill the process?"),
_T("Exec question"),
WXSIZEOF(signalNames), signalNames,
this);
switch ( sig )
{
default:
wxFAIL_MSG( _T("unexpected return value") );
// fall through
case -1:
// cancelled
return;
case wxSIGNONE:
case wxSIGHUP:
case wxSIGINT:
case wxSIGQUIT:
case wxSIGILL:
case wxSIGTRAP:
case wxSIGABRT:
case wxSIGEMT:
case wxSIGFPE:
case wxSIGKILL:
case wxSIGBUS:
case wxSIGSEGV:
case wxSIGSYS:
case wxSIGPIPE:
case wxSIGALRM:
case wxSIGTERM:
break;
}
if ( sig == 0 )
{
if ( wxProcess::Exists(pid) )
wxLogStatus(_T("Process %d is running."), pid);
else
wxLogStatus(_T("No process with pid = %d."), pid);
}
else // not SIGNONE
{
wxKillError rc = wxProcess::Kill(pid, (wxSignal)sig);
if ( rc == wxKILL_OK )
{
wxLogStatus(_T("Process %d killed with signal %d."), pid, sig);
}
else
{
static const wxChar *errorText[] =
{
_T(""), // no error
_T("signal not supported"),
_T("permission denied"),
_T("no such process"),
_T("unspecified error"),
};
wxLogStatus(_T("Failed to kill process %d with signal %d: %s"),
pid, sig, errorText[rc]);
}
}
}
// ----------------------------------------------------------------------------
// event handlers: exec menu
// ----------------------------------------------------------------------------
void MyFrame::DoAsyncExec(const wxString& cmd)
{
wxProcess *process = new MyProcess(this, cmd);
long pid = wxExecute(cmd, FALSE /* async */, process);
if ( !pid )
m_pidLast = wxExecute(cmd, FALSE /* async */, process);
if ( !m_pidLast )
{
wxLogError(_T("Execution of '%s' failed."), cmd.c_str());
@@ -366,7 +482,7 @@ void MyFrame::DoAsyncExec(const wxString& cmd)
}
else
{
wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str());
wxLogStatus(_T("Process %ld (%s) launched."), m_pidLast, cmd.c_str());
m_cmdLast = cmd;
}
@@ -543,6 +659,10 @@ void MyFrame::OnFileExec(wxCommandEvent& event)
DoAsyncExec(cmd);
}
// ----------------------------------------------------------------------------
// DDE stuff
// ----------------------------------------------------------------------------
#ifdef __WINDOWS__
bool MyFrame::GetDDEServer()
@@ -623,6 +743,10 @@ void MyFrame::OnDDERequest(wxCommandEvent& WXUNUSED(event))
#endif // __WINDOWS__
// ----------------------------------------------------------------------------
// various helpers
// ----------------------------------------------------------------------------
// input polling
void MyFrame::OnIdle(wxIdleEvent& event)
{