Add QStandardPaths::findExecutable.
Change-Id: If30a83622e2ac5af48e47a38b8f70fce73044d74 Reviewed-by: Thiago Macieira (Intel) <thiago.macieira@intel.com>
This commit is contained in:
parent
fa0ad643a6
commit
4b72c3f434
@ -176,6 +176,93 @@ QStringList QStandardPaths::locateAll(StandardLocation type, const QString &file
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static QStringList executableExtensions()
|
||||
{
|
||||
QStringList ret = QString::fromLocal8Bit(qgetenv("PATHEXT")).split(QLatin1Char(';'));
|
||||
if (!ret.contains(QLatin1String(".exe"), Qt::CaseInsensitive)) {
|
||||
// If %PATHEXT% does not contain .exe, it is either empty, malformed, or distorted in ways that we cannot support, anyway.
|
||||
ret.clear();
|
||||
ret << QLatin1String(".exe")
|
||||
<< QLatin1String(".com")
|
||||
<< QLatin1String(".bat")
|
||||
<< QLatin1String(".cmd");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static QString checkExecutable(const QString &path)
|
||||
{
|
||||
const QFileInfo info(path);
|
||||
if (info.isBundle())
|
||||
return info.bundleName();
|
||||
if (info.isFile() && info.isExecutable())
|
||||
return QDir::cleanPath(path);
|
||||
return QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
Finds the executable named \a executableName in the paths specified by \a paths,
|
||||
or the system paths if \a paths is empty.
|
||||
|
||||
On most operating systems the system path is determined by the PATH environment variable.
|
||||
|
||||
The directories where to search for the executable can be set in the \a paths argument.
|
||||
To search in both your own paths and the system paths, call findExecutable twice, once with
|
||||
\a paths set and once with \a paths empty.
|
||||
|
||||
Symlinks are not resolved, in order to preserve behavior for the case of executables
|
||||
whose behavior depends on the name they are invoked with.
|
||||
|
||||
\note On Windows, the usual executable extensions (from the PATHEXT environment variable)
|
||||
are automatically appended, so that for instance findExecutable("foo") will find foo.exe
|
||||
or foo.bat if present.
|
||||
|
||||
Returns the absolute file path to the executable, or an empty string if not found.
|
||||
*/
|
||||
QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths)
|
||||
{
|
||||
if (QFileInfo(executableName).isAbsolute())
|
||||
return checkExecutable(executableName);
|
||||
|
||||
QStringList searchPaths = paths;
|
||||
if (paths.isEmpty()) {
|
||||
QByteArray pEnv = qgetenv("PATH");
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
|
||||
const QLatin1Char pathSep(';');
|
||||
#else
|
||||
const QLatin1Char pathSep(':');
|
||||
#endif
|
||||
searchPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
QDir currentDir = QDir::current();
|
||||
QString absPath;
|
||||
#ifdef Q_OS_WIN
|
||||
static QStringList executable_extensions = executableExtensions();
|
||||
#endif
|
||||
|
||||
for (QStringList::const_iterator p = searchPaths.constBegin(); p != searchPaths.constEnd(); ++p) {
|
||||
const QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + executableName);
|
||||
#ifdef Q_OS_WIN
|
||||
const QString extension = QLatin1Char('.') + QFileInfo(executableName).suffix();
|
||||
if (!executable_extensions.contains(extension, Qt::CaseInsensitive)) {
|
||||
foreach (const QString &extension, executable_extensions) {
|
||||
absPath = checkExecutable(candidate + extension.toLower());
|
||||
if (!absPath.isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
absPath = checkExecutable(candidate);
|
||||
if (!absPath.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return absPath;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString QStandardPaths::displayName(StandardLocation type)
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QSTANDARDPATHS_H
|
||||
#define QSTANDARDPATHS_H
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
@ -87,6 +87,8 @@ public:
|
||||
static QStringList locateAll(StandardLocation type, const QString &fileName, LocateOptions options = LocateFile);
|
||||
static QString displayName(StandardLocation type);
|
||||
|
||||
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
|
||||
|
||||
private:
|
||||
// prevent construction
|
||||
QStandardPaths();
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <qfileinfo.h>
|
||||
#include <qhash.h>
|
||||
#include <private/qprocess_p.h>
|
||||
#include <qstandardpaths.h>
|
||||
#include <qtextcodec.h>
|
||||
#include <qthread.h>
|
||||
#include <qthreadpool.h>
|
||||
@ -2019,19 +2020,7 @@ QString QCoreApplication::applicationFilePath()
|
||||
Otherwise, the file path has to be determined using the
|
||||
PATH environment variable.
|
||||
*/
|
||||
QByteArray pEnv = qgetenv("PATH");
|
||||
QDir currentDir = QDir::current();
|
||||
QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
|
||||
for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
|
||||
if ((*p).isEmpty())
|
||||
continue;
|
||||
QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
|
||||
QFileInfo candidate_fi(candidate);
|
||||
if (candidate_fi.exists() && !candidate_fi.isDir()) {
|
||||
absPath = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
absPath = QStandardPaths::findExecutable(argv0);
|
||||
}
|
||||
|
||||
absPath = QDir::cleanPath(absPath);
|
||||
|
Loading…
Reference in New Issue
Block a user