ajith has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I need to make my perl script work on both Windows and Unix. I'm using "use Win32:service" statement in my script for querying status of some windows "services". On Unix, the same script queries the unix processes. But, when the script is run on Unix, I get a compilation error as: Can't locate Win32/Service.pm in @INC (@INC contains: /usr/perl5/5.00503/sun4- solaris /usr/perl5/5.00503 /usr/perl5/site_perl/5.005/sun4- solaris /usr/perl5/site_perl/5.005 .)..... Is it possible to use this statement in my script and not get this error message on unix ?? Something like this would help -- #ifdef WIN_OS // do something that is very windows specific - like: use Win32::Service; #else // unix // do something like "ps -eaf" etc #endif thanks !! -Ajith.
  • Comment on Can we do "use Win32:Service" on Unix ?"

Replies are listed 'Best First'.
Re: Can we do "use Win32:Service" on Unix ?"
by Corion (Patriarch) on Jan 27, 2005 at 14:40 UTC

    The Win32::Service module only works on Windows, and not on Unix. But you can prevent loading the module if your script is running under Unix like this:

    use strict; if ($^O =~ /MSWin32/) { my $res = eval "use Win32::Service"; die $@ if $@; die "Win32::Service did not return a true value" unless $res; # do Windows code } else { # Assume Unix, even though there are other platforms # do Unix code };
      Or

      if (eval("require(Win32::Service)")) { $runningOn = "windows"; } else { $runningOn="unix"; }

      Update - WUPS! Missed out the all important 'eval'! WUPS2 - As Corion correctly points out, I had extraneous "" characters in the eval. What say I just shut up?

      VGhpcyBtZXNzYWdlIGludGVudGlvbmFsbHkgcG9pbnRsZXNz

        Well ... not quite. The require will die ... so you need eval. Also, perl treats barewords special here - if you use a string, you'll need it to be 'Win32/Service.pm'. Stick to the barewords when possible ;-)

        $runningOn = 'unix'; eval { require Win32::Service; $runningOn = 'windows'; };

        Of course, we assume that Win32::Service never fails to load, but that's ok, since we make that assumption about most modules.

        No. perldoc -f require :

        ... In other words, if you try this:
        require Foo::Bar; # a splendid bareword

        The require function will actually look for the "Foo/Bar.pm" file in the directories specified in the @INC array.

        But if you try this:

        $class = 'Foo::Bar'; require $class; # $class is not a bareword #or require "Foo::Bar"; # not a bareword because of the ""

        The require function will look for the "Foo::Bar" file in the @INC array and will complain about not finding "Foo::Bar" there.

        In this case you can do:

        eval "require $class";

        ...

        Personally, I've used UNIVERSAL::require, which allows me to do

        "Win32::Service"->require()

        but I don't think that UNIVERSAL::require is really fit for production use.

      Thanks, This works on unix pretty well, but when run on windows it cribs with this error message - Win32::Service did not return a true value at .... The point is, we need this work on both windows and unix. Is there a way out ? pls lemme know. -ajith.

        Sorry - I gave you some wrong information. The use command does not return the true value that require returns. So you need to throw out the second line that contains did not return a true value of my code:

        use strict; if ($^O =~ /MSWin32/) { my $res = eval "use Win32::Service"; die $@ if $@; # do Windows code } else { # Assume Unix, even though there are other platforms # do Unix code };