0

I'm working on an implementation to force the exit of a process by PID in QT. The only way I found to solve this problem is using the following lines of code:

QString processToKill = "taskkill /F /PID " + QString(getAppPid());
system(processToKill.toStdString().c_str());    

These lines do their job and works well, the only detail I have found is that when executing this command a console opens and closes quickly (a flicker). Is there any way to prevent this behavior?

BadRobot
  • 265
  • 1
  • 9
  • 2
    Don't use `system()` - *ever*. It's a security nightmare. At the very least, use `QProcess` instead. – Jesper Juhl Sep 19 '22 at 21:34
  • 1
    @JesperJuhl thanks for your suggestion. I found I can use `QProcess::execute("taskkill", QStringList() << "/F" << "/PID" << QString(getAppPid));` instead of `system`. – BadRobot Sep 19 '22 at 22:01
  • Also keep an eye out for malicious little s placing a taskkill executable in the path to be found before the real one. Best if you use an absolute path here. – user4581301 Sep 19 '22 at 22:06
  • @user4581301 Can you provide more information about you commented?. I'm confused – BadRobot Sep 19 '22 at 22:24
  • 1
    When you provide a relative path, the system will look in the current working directory and then search the system path for a program named taskkill. If I drop a little script called taskkill that, say, formats the hard disk, in the right spot so that the system finds it first, when the the victim runs the program... They gonna be maaaaaad! – user4581301 Sep 19 '22 at 22:40
  • Anyone can provide more detailed information about why is a bad practice to use `system()`?. – BadRobot Sep 20 '22 at 15:29

2 Answers2

1

If you are using system() you cannot avoid the occasional flash of the console window. Were you to use any other program you might even see its window flash.

I won’t go into any detail about the security flaws inherent to using system().

The correct way to do this with the Windows API.

Even so, you are taking a sledgehammer approach. You should first signal the process to terminate gracefully. If it hasn’t done so after a second or two, only then should you crash it.

The SO question “How to gracefully terminate a process” details several options to properly ask a process to terminate.

If that fails, then you can simply kill a process using the TerminateProcess() Windows API function (which is what taskkill /f does). Here is a good example of how to do that: https://github.com/malcomvetter/taskkill

The relevant code has the following function:

BOOL TerminateProcess(int pid)
{
    WORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL bInheritHandle = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, pid);
    if (hProcess == NULL)
        return FALSE;
    BOOL result = TerminateProcess(hProcess, 1);
    CloseHandle(hProcess);
    return(TRUE);
}

Microsoft has a page all about Terminating a Process that you may wish to review as well.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
0

If this is a windows program create a program that uses a WinMain entry point rather than main, and set the linker subsystem to windows rather than console.

Just because it uses WinMain does not mean that you must create a window, it merely means you don't automatically get a console.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23