in reply to Detecting if a program or file exists

I see lots of correct information scattered about this node. The answer to your question largely depends on what exactly you need to know. Do you need to know what Perl version is installed, or just that a minimum is available (i.e. "at least Perl 5.6.1")? Do you need to behave differently depending on the answer, or do you just need to refuse to run with an error?

To find out the version of Perl, as it says in perlvar, you can use the special variable $], which is the "Perl version/1000". So, Perl 5.8.6 is identified by $] == 5.008006. If you want "Perl >= 5.6" you can use:

if ( $] >= 5.006 ) { print "This is good, your Perl is version $]\n"; } else { warn "Your Perl is only version $]: Bad!"; }

However, if all you need is to make sure that you have a minimum level of Perl (say, 5.6.1) available before you run, you can use:

require 5.006_001; # check at run-time, at this point in code. use 5.006_001; # check at compile-time

If you need to kick off a process based on this, you could do this:

eval { require 5.006_001; }; if ($@) { # $@ is set if the 'require' dies warn "Your Perl is too old." system ('n:\\install\\upgrade-perl.exe'); # imaginary }

Since you mention requiring modules to be installed and checking for the existence of files on Windows (say, to see if another app is installed), I'll address those as well.

First, you should check out CPAN and CPANPLUS modules, which might help you automate checking for and installing modules. Aside from that, though, you can require a module, even specifying what minimum version to use.

# import a version of a module at compile time, die on failure use Module 1.02; # dies unless Module is at least v1.02 # at runtime, find version and act on it. eval { require Module; # if not installed, dies (go to end of eval) if ($Module::VERSION >= 1.02) { print "Module version is OK\n"; } else { warn "Module is installed, but is too old"; # maybe upgrade it here } } if ($@) { # run if 'require Module' fails warn "Module is not available"; # maybe install it here }

Checking for a file on Windows is easy enough using the -X class of function. Windows has different ideas about what makes a file executable, so I suggest just checking for the file to exist:

if (-f 'c:\\program files\\some app\\app.exe') { print "APP is installed, good.\n"; } else { warn "APP not installed!"; }

If you use a recent ActiveState perl, you can also use UNIX-ish paths (e.g. 'c:/program files/', but if use the backslashes, you have to double them up so they are escaped properly. If this has to work on multiple platforms, check out File::Spec and File::Spec::Functions.

In any case, checking a version by scanning the directory size is a Very Bad Thing, since various installed modules and even quirks of the filesystem can alter the directory sizes. If none of the above helps you, maybe you could clarify your question and tell us more about what you're trying to accomplish.

<-radiant.matrix->
A collection of thoughts and links from the minds of geeks
The Code that can be seen is not the true Code
"In any sufficiently large group of people, most are idiots" - Kaa's Law