Search code examples
c++qtqt4qprocess

Command Line closing despite using QProcess::startDetached()


I'm trying to open a server via batch file in cmd.exe in my Qt application. Despite I'm using QProcess::startDetached() to start the command line it closes immediately after start. The server is starting, but instead of "serving" the process is killed. Here is my code:

void DICOMReceiver::startReceiver()
{
    QProcess receiver;
    boost::filesystem::path dbDir = boost::filesystem::absolute(databaseDirectory.toStdString());
    receiver.startDetached("cmd.exe", QStringList() << "/c" <<
                           "dcmrcv.bat" << "AETitle:11112" << "-dest " << dbDir.string().c_str());
    receiver.waitForStarted();
}

When I run the batch file manually in the cmd.exe it is working as desired. Does anybody have an idea how to keep the process running so that I can use the server?


Solution

    1. startDetached is a static function. You don't need a process instance.

    2. You should pass a working directory to startDetached. For all I know it "closes" because the batch file doesn't exist where it's looking for it.

    3. Your waitForStarted() call is a no-op since the startDetached method does not know anything about your receiver instance. You simply wrote obfuscated C++ that deceives you. There is no way to wait for a detached process to start when using Qt. A detached process is fire-and-forget.

    4. Do not use waitForXxx methods, as they block the thread they're in, and make the UI unresponsive. Use signal-slot connections and write asynchronous code instead.

    So, your method should be fixed as follows:

    void DICOMReceiver::startReceiver()
    {
      boost::filesystem::path dbDir =
        boost::filesystem::absolute(databaseDirectory.toStdString());
      // FIXME
      const QString batchPath = QStringLiteral("/path/to/the/batch/file");
      QProcess::startDetached("cmd.exe", QStringList() << "/c"
                              << "dcmrcv.bat" << "AETitle:11112" << "-dest "
                              <<< dbDir.string().c_str(), batchPath);
    }