Omar Murcia
Omar Murcia

Reputation: 567

How to check if a program exists in path using Qt?

I have this code:

QProcess* proceso = new QProcess();
QString programa = "unknow -v";
proceso->start(programa);
proceso->waitForFinished();

QString normal = proceso->readAllStandardOutput();
QString errores = proceso->readAllStandardError();

qDebug() << normal;
qDebug() << errores;

The output I get is:

"" ""

But I want get and error that says: Command not found.

Thanks in advance.

EDITED:

I found this solution using Qt:

 int result = system("unknow -v");
 if(result!=0) {
   qDebug() << "No está instalado nasm";
 } else {
   qDebug() << "Está instalado.";
 }

But I want get an output into a QString.

Upvotes: 3

Views: 3112

Answers (3)

Gerhard Stein
Gerhard Stein

Reputation: 1563

The question is about if you are able to run the command aka if the command exists on your system. This means NOT trying to launch it and see what happens, huge difference!

How about this?

I like the idea of which but it won't work under Windows, AFAIK.

    QProcess findProcess;
    QStringList arguments;
    arguments << myCommand;
    findProcess.start("which", arguments);
    findProcess.setReadChannel(QProcess::ProcessChannel::StandardOutput);

    if(!findProcess.waitForFinished())
        return false; // Not found or which does not work

    QString retStr(findProcess.readAll());

    retStr = retStr.trimmed();

    QFile file(retStr);
    QFileInfo check_file(file);
    if (check_file.exists() && check_file.isFile())
        return true; // Found!
    else
        return false; // Not found!

Upvotes: 1

Sascha
Sascha

Reputation: 1136

Please try this:

QProcess program;
QString commandToStart= "unknown -v";
QStringList environment = program.systemEnvironment();
program.start(commandToStart);
bool started = program.waitForStarted();
if (!program.waitForFinished(10000)) // 10 Second timeout
    program.kill();

int exitCode = program.exitCode();
QString stdOutput = QString::fromLocal8Bit(program.readAllStandardOutput());
QString stdError = QString::fromLocal8Bit(program.readAllStandardError());

If started is true, the program could be started. That usually means, it was in the path. If it's false, check whether the path in environment is correct.

The exitCode is only helpful, if the process could actually be started and something else went wrong. If the program could not be started at all, exitCode will be 0 and stdOutput and stdError will be empty! That may be misleading.

Upvotes: 1

You could fetch the value of your PATH using getenv("PATH") then split it on colons (or semi-colons for Windows), iterate on every directory there, test that it contains a unknow file, etc....

So you don't need any Qt thing for that. Just plain C++ (string operations).

(this is not bullet-proof: some other process might modify a directory in your $PATH between such a test and the actual start of process; but it should often be enough in practice)

On POSIX systems, you might run your command thru sh -c (e.g. run sh -c 'unknow -v'), but be careful of escapes and code injections (so check the string unknow -v for things like single and double quotes, etc...)

You could also use popen(3) perhaps using which but I don't recommend that (too complex).

I am not sure it is worth the trouble anyway. Why don't you simply just run the program.... I don't see much difference between a missing executable and a command failing for many other reasons.

Upvotes: 1

Related Questions