diff --git a/doc/global/externalsites/external-resources.qdoc b/doc/global/externalsites/external-resources.qdoc index 1ef261caf6..e87bcd4959 100644 --- a/doc/global/externalsites/external-resources.qdoc +++ b/doc/global/externalsites/external-resources.qdoc @@ -565,3 +565,8 @@ \externalpage https://www.unicode.org/ \title Unicode standard */ + +/*! + \externalpage https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw + \title CreateProcess +*/ diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 6b6247e92d..3378412502 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -488,6 +488,61 @@ void QProcessPrivate::Channel::clear() \note QProcess is not supported on VxWorks, iOS, tvOS, or watchOS. + \section1 Finding the Executable + + The program to be run can be set either by calling setProgram() or directly + in the start() call. The effect of calling start() with the program name + and arguments is equivalent to calling setProgram() and setArguments() + before that function and then calling the overload without those + parameters. + + QProcess interprets the program name in one of three different ways, + similar to how Unix shells and the Windows command interpreter operate in + their own command-lines: + + \list + \li If the program name is an absolute path, then that is the exact + executable that will be launched and QProcess performs no searching. + + \li If the program name is a relative path with more than one path + component (that is, it contains at least one slash), the starting + directory where that relative path is searched is OS-dependent: on + Windows, it's the parent process' current working dir, while on Unix it's + the one set with setWorkingDirectory(). + + \li If the program name is a plain file name with no slashes, the + behavior is operating-system dependent. On Unix systems, QProcess will + search the \c PATH environment variable; on Windows, the search is + performed by the OS and will first the parent process' current directory + before the \c PATH environment variable (see the documentation for + \l{CreateProcess} for the full list). + \endlist + + To avoid platform-dependent behavior or any issues with how the current + application was launched, it is adviseable to always pass an absolute path + to the executable to be launched. For auxiliary binaries shipped with the + application, one can construct such a path starting with + QCoreApplication::applicationDirPath(). Similarly, to explicitly run an + executable that is to be found relative to the directory set with + setWorkingDirectory(), use a program path starting with "./" or "../" as + the case may be. + + On Windows, the ".exe" suffix is not required for most uses, except those + outlined in the \l{CreateProcess} documentation. Additionally, QProcess + will convert the Unix-style forward slashes to Windows path backslashes for + the program name. This allows code using QProcess to be written in a + cross-platform manner, as shown in the examples above. + + QProcess does not support directly executing Unix shell or Windows command + interpreter built-in functions, such as \c{cmd.exe}'s \c dir command or the + Bourne shell's \c export. On Unix, even though many shell built-ins are + also provided as separate executables, their behavior may differ from those + implemented as built-ins. To run those commands, one should explicitly + execute the interpreter with suitable options. For Unix systems, launch + "/bin/sh" with two arguments: "-c" and a string with the command-line to be + run. For Windows, due to the non-standard way \c{cmd.exe} parses its + command-line, use setNativeArguments() (for example, "/c dir d:"). + \section1 Communicating via Channels Processes have two predefined output channels: The standard @@ -568,15 +623,6 @@ void QProcessPrivate::Channel::clear() \snippet process/process.cpp 0 - \section1 Notes for Windows Users - - Some Windows commands (for example, \c dir) are not provided by - separate applications, but by the command interpreter itself. - If you attempt to use QProcess to execute these commands directly, - it won't work. One possible solution is to execute the command - interpreter itself (\c{cmd.exe} on some Windows systems), and ask - the interpreter to execute the desired command. - \sa QBuffer, QFile, QTcpSocket */ @@ -1905,7 +1951,8 @@ QByteArray QProcess::readAllStandardError() /*! Starts the given \a program in a new process, passing the command line - arguments in \a arguments. + arguments in \a arguments. See setProgram() for information about how + QProcess searches for the executable to be run. The QProcess object will immediately enter the Starting state. If the process starts successfully, QProcess will emit started(); otherwise, @@ -2214,7 +2261,12 @@ QString QProcess::program() const Set the \a program to use when starting the process. This function must be called before start(). - \sa start(), setArguments(), program() + If \a program is an absolute path, it specifies the exact executable that + will be launched. Relative paths will be resolved in a platform-specific + manner, which includes searching the \c PATH environment variable (see + \l{Finding the Executable} for details). + + \sa start(), setArguments(), program(), QStandardPaths::findExecutable() */ void QProcess::setProgram(const QString &program) {