Skip to content

Instantly share code, notes, and snippets.

@PBfordev
Last active October 27, 2021 20:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PBfordev/847b002f2721791ea22ccdc87685f0de to your computer and use it in GitHub Desktop.
Save PBfordev/847b002f2721791ea22ccdc87685f0de to your computer and use it in GitHub Desktop.
Tests whether wxProcess::OnTerminate() is called when the process is killed
#include <wx/wx.h>
#include <wx/process.h>
class MyProcess : public wxProcess
{
public:
void OnTerminate(int pid, int status) override
{
wxLogMessage("MyProcess::OnTerminate(): pid = %d, status = %d", pid, status);
}
};
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(nullptr, wxID_ANY, "Test")
{
wxPanel* mainPanel = new wxPanel(this);
wxSizer* mainPanelSizer = new wxBoxSizer(wxVERTICAL);
m_startButton = new wxButton(mainPanel, wxID_ANY, "Start process...");
mainPanelSizer->Add(m_startButton, wxSizerFlags().Expand().Border());
wxTextCtrl* logCtrl = new wxTextCtrl(mainPanel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
wxLog::DisableTimestamp();
mainPanelSizer->Add(logCtrl, wxSizerFlags().Proportion(1).Expand().Border());
m_timer.SetOwner(this);
Bind(wxEVT_BUTTON, &MyFrame::OnStartProcess, this);
Bind(wxEVT_TIMER, &MyFrame::OnKillProcessTimer, this);
SetClientSize(800, 600);
SetSizer(mainPanelSizer);
}
private:
wxButton* m_startButton;
MyProcess m_process;
wxTimer m_timer;
wxString m_command{"cmd"};
void OnStartProcess(wxCommandEvent&)
{
wxString command = wxGetTextFromUser("Enter command to execute", "Execute", m_command);
if ( command.empty() )
return;
m_command = command;
if ( wxExecute(m_command, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, &m_process) )
{
wxLogMessage("Process '%s' with pid %ld will be killed in 3 sec.", m_command, m_process.GetPid());
m_timer.StartOnce(3000);
m_startButton->Disable();
}
}
void OnKillProcessTimer(wxTimerEvent&)
{
wxSignal sig = wxSIGTERM;
if ( wxMessageBox("Press 'Yes' to use wxSIGTERM, 'No' to use wxSIGKILL.", "Select", wxYES_NO) != wxYES )
sig = wxSIGKILL;
wxLogMessage("Attempting to kill '%s' with %s.", m_command, sig == wxSIGKILL ? "wxSIGKILL" : "wxSIGTERM");
const wxKillError killResult = wxProcess::Kill(m_process.GetPid(), sig);
if ( killResult == wxKILL_OK )
{
wxLogMessage("Process killed successfully.");
}
else
{
wxString killResultString;
switch ( killResult )
{
case wxKILL_BAD_SIGNAL:
killResultString = "wxKILL_BAD_SIGNAL";
break;
case wxKILL_ACCESS_DENIED:
killResultString = "wxKILL_ACCESS_DENIED";
break;
case wxKILL_NO_PROCESS:
killResultString = "wxKILL_NO_PROCESS";
break;
default:
killResultString = "wxKILL_ERROR";
}
wxLogError("Could not kill the process, wxProcess::Kill() returned %s.", killResultString);
}
m_startButton->Enable();
}
};
class MyApp : public wxApp
{
bool OnInit() override
{
(new MyFrame)->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment