Home > Software design >  Qt startDetached fails under Qt 5.15.2
Qt startDetached fails under Qt 5.15.2

Time:05-01

I'm updating some old Qt 5.6 code to Qt 5.15.2

The Qt C code below opens a dos prompt, the runs a bat file, staying open when done.

cstring = "cmd /k "  QDir::currentPath() "/cpath.bat";

QProcess::startDetached(cstring);

This code works fine under 5.6, does nothing under 5.15.2

How do I fix this for Qt 5.15.2?

CodePudding user response:

You need to split the command to program and arguments. See https://doc.qt.io/qt-5/qprocess.html#startDetached-1

In your case it should be

QProcess::startDetached("cmd", {"/k", QDir::currentPath()   "/cpath.bat"});

The advantage is that now you do not need to worry for example about enclosing paths containing spaces in quotes. Consider if your current path would be "C:\my path". Then your version from Qt 5.6 would not work. While the version I presented in this answer will work out of the box. I guess it was exactly this reason that the old overload was prone to this kind of bugs that Qt decided to remove it and use only the new overload.

CodePudding user response:

Ok, with my previous answer I though that the problem was with the way you are passing the arguments. But as it seems the problem is with showing the terminal... Since I am doing the same in one of my projects (HiFile file manager), I had a look how I am doing it. So here it is.

class DetachableProcess : public QProcess
{
public:
    explicit DetachableProcess(QObject *parent = nullptr) : QProcess(parent)
    {
    }

    bool detach()
    {
        if (!waitForStarted())
        {
            return false;
        }
        setProcessState(QProcess::NotRunning);
        return true;
    }
};

And then use it like this:

DetachableProcess process;
process.setCreateProcessArgumentsModifier( // this probably did the trick you need
    [](QProcess::CreateProcessArguments *args)
    {
        args->flags |= CREATE_NEW_CONSOLE;
        args->startupInfo->dwFlags &=~ STARTF_USESTDHANDLES;
    });

process.start("cmd", {"/k", QDir::currentPath()   "/cpath.bat"}); // here are your params...
process.detach();

I am afraid I cannot give more explanation why this complicated method works, I do not know it. And I do not know why it was changed in Qt.

I hope it will work for you. It works for me in Qt 6.2.4, which I am currently using.

  •  Tags:  
  • c qt
  • Related