3

I need to detect if app is present in system. I use for it std.process the next code is trow exception if executable command do not exists:

try
{
    auto ls = execute(["fooapp"]);
    if (ls.status == 0) writeln("fooapp is Exists!\n");
}

catch (Exception e)
{
        writeln("exception");
}

Is there any better way to check if app is exists without throwing exception?

Suliman
  • 1,301
  • 2
  • 11
  • 19

2 Answers2

3

I'd be very worried about simply running a command. Even if you know what it's supposed to do, if there were another program with the same name on the system (be it accidentally or maliciously), you could have weird - and possibly very bad - side effects to simply running the command. AFAIK, doing this properly is going to be system specific, and the best that I can suggest is to take advantage of whatever command line shell is on the system.

The answers to these two questions seem to provide good information on how to do this on Linux, and I expect that it's valid for the BSDs as well. It might even be valid for Mac OS X as well, but I don't know, since I'm not familiar with what Mac OS X has in terms of command line shells by default.

How to check if command exists in a shell script?

Check if a program exists from a Bash script

The answer seems to pretty much boil down to using the type command, but you should read the details in the answers. For Windows, a quick search reveals this:

Is there an equivalent of 'which' on the Windows command line?

It seems to provide several different ways to attack the problem on Windows. So, from what's there, it should be possible to figure out a shell command to run on Windows to tell you whether a particular command exists or not.

Regardless of the OS though, what you're going to need to do is something like

bool commandExists(string command)
{
    import std.process, std.string;
    version(linux)
        return executeShell(format("type %s", command)).status == 0;
    else version(FreeBSD)
        return executeShell(format("type %s", command)).status == 0;
    else version(Windows)
        static assert(0, "TODO: Add Windows magic here.");
    else version(OSX)
        static assert(0, "TODO: Add Mac OS X magic here.");
    else
        static assert(0, "OS not supported");
}

And it may be that on some systems, you'll actually have to parse the output from the command to see whether it gave you the right result rather than looking at the status. Unfortunately though, this is exactly the sort of thing that's going to be very system-specific.

Community
  • 1
  • 1
Jonathan M Davis
  • 34,779
  • 15
  • 69
  • 99
1

You can use this function under windows(so this is the Windows magic to add as said in the other answer...), it checks if a file exists in the environment, by default in PATH:

string envFind(in char[] filename, string envVar = "PATH")
{  
    import std.process, std.array, std.path, std.file;
    auto env = environment.get(envVar);
    if (!env) return null;
    foreach(string dir; env.split(";")) {
        auto maybe = dir ~ dirSeparator ~ filename; 
        if (maybe.exists) return maybe.idup;
    }
    return null;
}

basic usage:

if (envFind("cmd.exe") == "")  assert(0, "cmd is missing");
if (envFind("explorer.exe") == "")  assert(0, "explorer is missing");
if (envFind("mspaint.exe") == "") assert(0, "mspaintis missing");
Abstract type
  • 1,851
  • 2
  • 13
  • 23