Solved QProcess close child processes issue
-
Hi! I want to close/terminate the
Inno Setup
installation process using my application. I have tried these methods ofQProcess
:close()
,terminate()
,kill()
but it only closes the 1 process and all childInno Setup
processes continue running. How to close allInno Setup
processes? Any ideas? Thanks. -
I fixed it using the
Win API
.Code:
DWORD pid = NULL; HWND hWnd = FindWindow(NULL, QString("SetupTitle").toStdWString().c_str()); GetWindowThreadProcessId(hWnd, &pid); HANDLE handle = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, TRUE, pid); DWORD res = TerminateProcess(handle, NULL); if (res == NULL) { QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("Process is not found."), QMessageBox::Ok); } CloseHandle(handle);
Info:
- It gets the
pid
from the window title - Creates the
handle
with the processpid
- Terninates the process using
TerminateProcess
function - Closes the handle
Also I added the additional check if process is not detected. The issue is resolved.
- It gets the
-
This solution works but it has some cons. For example, you need manually specify the window title in the
FindWindow
function, add some checking if it's localized in the different languages etc.So, I have checked the
Microsoft Spy++
app, read some docs, then I have created another solution.Code:
DWORD pid = NULL; HWND hWnd = FindWindow(QString("TWizardForm").toStdWString().c_str(), NULL); std::wstring title; title.reserve(GetWindowTextLength(hWnd) + 1); GetWindowText(hWnd, const_cast<WCHAR *>(title.c_str()), title.capacity()); HWND wizardhWnd = FindWindowEx(NULL, NULL, QString("TWizardForm").toStdWString().c_str(), title.c_str()); GetWindowThreadProcessId(wizardhWnd, &pid); HANDLE handle = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, TRUE, pid); DWORD res = TerminateProcess(handle, NULL); if (res != NULL) { QMessageBox::information(this, "Information", "Process has been closed!", QMessageBox::Ok); } else { QMessageBox::critical(this, "Error", "Process is not found!", QMessageBox::Ok); } CloseHandle(handle);
Info:
- I get
TWizardForm
class fromMicrosoft Spy++
app (TWizardForm
class is used byInno Setup
) - Get the window title using
GetWindowText
method FindWindowEx
now will find the process for the class (TWizardForm
) and appropriate window title- Get the process
pid
usingGetWindowThreadProcessId
function - Terminate the process
- Close the handle
It will detect the appropriate process and terminate it. I think it's better solution than the previous one.
- I get