3

Say I have an application I write, that relies for some task on an externat app (lets call it "tool") that is installed on my machine. In my program, I call it with system( "tool myarguments" ); , works fine.

Now, I want to distribute my app. Of course, the end-user might not have "tool" installed on his machine, so I would like my app to check this, and printout a message for the user. So my question is:

Is there a portable way to check for the existence of an app on the machine? (assuming we know its name and it is accessible through the machine's shell).

Additional information: First idea was to check the existence of the binary file, but:

  • This is platform dependent,
  • depending on how it has been installed (build from sources, installed through package,...), it might not always be in the same place, although it can be accessed through local path.

My first opinion on this question is "No", but maybe somebody has an idea ?

Reference: system()

Related: stackoverflow.com/questions/7045879

Community
  • 1
  • 1
kebs
  • 6,387
  • 4
  • 41
  • 70
  • is it possible for you to run `tool` in a way that has no side effect (apart from printing version or usage information) and having it return a 0 exit code ? – SirDarius Oct 10 '13 at 15:28
  • @SirDarius I'm not sure I understand your comment. I assume yes, I could, but the problem is what happens if it is not present ? – kebs Oct 10 '13 at 15:30
  • Ah. Just found a related question (but just for Linux), didn't find it before: http://stackoverflow.com/questions/7045879/ – kebs Oct 10 '13 at 15:31
  • Simply put, system("tool") will return a non-zero value if it is not found. (tested on Windows : 1, on Linux 7F00) – SirDarius Oct 10 '13 at 15:31

2 Answers2

2

If you use the Qt toolkit, QProcess may help you.

Edit: and look for QProcess::error() return value: if it is QProcess::FailedToStart , then either it is not installed, or you have insufficient permissions.

Polentino
  • 907
  • 5
  • 16
  • The problem is that, although this will often work on Linux systems (where most executables are in the `PATH`), on Windows usually it isn't the case, and often you have to hunt the registry to locate where some executable may be installed. – Matteo Italia Oct 10 '13 at 15:22
  • @MatteoItalia I added an explanation right after posting it, because i realized my answer was vague. Anyway that's what system() does too, so i think it is what the OP asked for. – Polentino Oct 10 '13 at 15:22
  • @MatteoItalia good point, on Windows that is such a pita indeed – Polentino Oct 10 '13 at 15:24
  • For linux the return value of `which PROG` should do that without actually starting something. – dornhege Oct 10 '13 at 15:28
  • @dornhege Seems to do the job, indeed. But is `which` present on all (common) linux distros ? – kebs Oct 10 '13 at 15:33
  • 1
    @kebs I've never heard of a distro without `which`. – piedar Oct 10 '13 at 15:37
  • @piedar: still, `which` is not POSIX. You should use [`command -v`](http://stackoverflow.com/a/762682/214671), or simply check if the return value of `system` is 127 (notice that this is correct only on POSIX systems, on Windows 127 has no special value). – Matteo Italia Oct 10 '13 at 15:39
1

If running the tool without argument has no side-effect, and is expected to return an exit code of 0, you can use system("tool") to check tool's existence.

You can check whether the command has been found by checking system's return value like this:

int ret = system("tool");
if (ret != 0) {
    std::cout << "tool is not here, move along\n";
}

It is portable in the sense that system is expected to return 0 if all goes well and the command return status is 0 too.

For example, on Linux, running system("non_existing_command") returns 0x7F00 (same type of value as returned by wait()).

On Windows, it returns 1 instead.

SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • Accepting answer, although this behaviour seems to be not guaranteed by standard ("Implementation-defined value" is the common term). Thanks anyway, it works, at least ;-) – kebs Oct 12 '13 at 17:02