3

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.

Omar Murcia
  • 547
  • 2
  • 11
  • 26

3 Answers3

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.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • `popen` would be pretty straightforward. Use `fgets` to read a line, then `pclose` it. If `pclose` returns non-zero, the command you were looking for didn't exist (`pclose` would return the exit code of the `which` command). – Jason C Feb 03 '22 at 04:11
  • PS on Windows you can use `_popen` (stdio.h), as long as you're not doing a UWP build. – Jason C Feb 03 '22 at 04:13
1

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.

Sascha
  • 986
  • 10
  • 30
1

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!
Gerhard Stein
  • 1,543
  • 13
  • 25