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:
		@@ -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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user