Add non-static QProcess::startDetached

The three static QProcess::startDetached overloads support a limited number of
features: program, arguments and working directory. To support more features of
QProcess (without adding a plethora of overloads) we add a non-static method
startDetached that can be used as follows:

QProcess p;
p.setProgram("cat");
p.setArguments("meow");
p.setWorkingDirectory("/tmp");
if (!p.startDetached())
    qWarning("Cannot start process.");

We plan to add support for nativeArguments, processEnvironment,
standard{Output|Error}File and maybe more in subsequent commits.

[ChangeLog][QtCore][QProcess] Added non-static QProcess::startDetached
to support more features for detached processes.

Task-number: QTBUG-2058
Task-number: QTBUG-2284
Task-number: QTBUG-37656
Task-number: QTBUG-52405
Task-number: QTBUG-57687
Change-Id: If6fdd57ecb28cd13aa5fff566216a4177f81d339
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
Joerg Bornemann 2016-05-30 17:22:05 +02:00
parent 6505062f58
commit 31e782cc96
5 changed files with 62 additions and 21 deletions

View File

@ -2111,6 +2111,46 @@ void QProcess::start(OpenMode mode)
d->start(mode);
}
/*!
\since 5.10
Starts the program set by setProgram() with arguments set by setArguments()
in a new process, and detaches from it. Returns \c true on success;
otherwise returns \c false. If the calling process exits, the
detached process will continue to run unaffected.
\b{Unix:} The started process will run in its own session and act
like a daemon.
The process will be started in the directory set by setWorkingDirectory().
If workingDirectory() is empty, the working directory is inherited
from the calling process.
\note On QNX, this may cause all application threads to
temporarily freeze.
If the function is successful then *\a pid is set to the process
identifier of the started process.
\sa start()
\sa startDetached(const QString &program, const QStringList &arguments,
const QString &workingDirectory, qint64 *pid)
\sa startDetached(const QString &command)
*/
bool QProcess::startDetached(qint64 *pid)
{
Q_D(QProcess);
if (d->processState != NotRunning) {
qWarning("QProcess::startDetached: Process is already running");
return false;
}
if (d->program.isEmpty()) {
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return false;
}
return d->startDetached(pid);
}
/*!
Starts the program set by setProgram() with arguments set by setArguments().
The OpenMode is set to \a mode.
@ -2445,6 +2485,8 @@ int QProcess::execute(const QString &command)
}
/*!
\overload startDetached()
Starts the program \a program with the arguments \a arguments in a
new process, and detaches from it. Returns \c true on success;
otherwise returns \c false. If the calling process exits, the
@ -2452,16 +2494,10 @@ int QProcess::execute(const QString &command)
Argument handling is identical to the respective start() overload.
\b{Unix:} The started process will run in its own session and act
like a daemon.
The process will be started in the directory \a workingDirectory.
If \a workingDirectory is empty, the working directory is inherited
from the calling process.
\note On QNX, this may cause all application threads to
temporarily freeze.
If the function is successful then *\a pid is set to the process
identifier of the started process.
@ -2472,10 +2508,11 @@ bool QProcess::startDetached(const QString &program,
const QString &workingDirectory,
qint64 *pid)
{
return QProcessPrivate::startDetached(program,
arguments,
workingDirectory,
pid);
QProcess process;
process.setProgram(program);
process.setArguments(arguments);
process.setWorkingDirectory(workingDirectory);
return process.startDetached(pid);
}
/*!
@ -2484,11 +2521,14 @@ bool QProcess::startDetached(const QString &program,
bool QProcess::startDetached(const QString &program,
const QStringList &arguments)
{
return QProcessPrivate::startDetached(program, arguments);
QProcess process;
process.setProgram(program);
process.setArguments(arguments);
return process.startDetached();
}
/*!
\overload
\overload startDetached()
Starts the command \a command in a new process, and detaches from it.
Returns \c true on success; otherwise returns \c false.
@ -2506,9 +2546,10 @@ bool QProcess::startDetached(const QString &command)
if (args.isEmpty())
return false;
const QString prog = args.takeFirst();
return QProcessPrivate::startDetached(prog, args);
QProcess process;
process.setProgram(args.takeFirst());
process.setArguments(args);
return process.startDetached();
}
QT_BEGIN_INCLUDE_NAMESPACE

View File

@ -163,6 +163,7 @@ public:
void start(const QString &command, OpenMode mode = ReadWrite);
#endif
void start(OpenMode mode = ReadWrite);
bool startDetached(qint64 *pid = nullptr);
bool open(OpenMode mode = ReadWrite) Q_DECL_OVERRIDE;
QString program() const;

View File

@ -368,8 +368,7 @@ public:
qint64 pipeWriterBytesToWrite() const;
#endif
static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(),
qint64 *pid = 0);
bool startDetached(qint64 *pPid);
int exitCode;
QProcess::ExitStatus exitStatus;

View File

@ -925,7 +925,7 @@ bool QProcessPrivate::waitForDeadChild()
return true;
}
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
bool QProcessPrivate::startDetached(qint64 *pid)
{
QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);

View File

@ -859,7 +859,7 @@ static bool startDetachedUacPrompt(const QString &programIn, const QStringList &
return true;
}
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
bool QProcessPrivate::startDetached(qint64 *pid)
{
static const DWORD errorElevationRequired = 740;
@ -876,7 +876,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
};
success = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, FALSE, dwCreationFlags, 0,
workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(),
workingDirectory.isEmpty() ? 0 : (wchar_t*)workingDirectory.utf16(),
&startupInfo, &pinfo);
if (success) {
@ -885,7 +885,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
if (pid)
*pid = pinfo.dwProcessId;
} else if (GetLastError() == errorElevationRequired) {
success = startDetachedUacPrompt(program, arguments, workingDir, pid);
success = startDetachedUacPrompt(program, arguments, workingDirectory, pid);
}
return success;