How do I enable Win32 modules only when I run my Perl script on Windows?

I have a problem for which I cannot find an answer.

With Perl, I need to use a script for both Windows and Unix platforms. The problem is that on Windows we are using Win32 modules like Win32 :: Process and these modules do not exist on unix.

I need a way to enable these Win32 modules on Windows only.

if($^O =~ /win/i)
{
    use win32::process qw(CREATE_NEW_CONSOLE);
}
else
{
    #unix fork
}

      

The problem is that the Windows use statement. No matter what I try to do it doesn't compile on unix.

I've tried using dynamic evaluations, requires, BEGIN, etc.

Is there a good solution to this problem? Any help would be greatly appreciated.

Thanks in advance,

Dan


Update:

A staff member pointed out to me that this is the correct way to do it.

require Win32;
require Win32::Process;

my $flag = Win32::Process::CREATE_NEW_CONSOLE();

Win32::Process::Create($process, 
    $program, 
    $cmd, 
    0, 
    $flag, ".") || die ErrorReport();

print "Child started, pid = " . getPID() . "\n";

      

Thanks everyone for your help!

Dan

+1


a source to share


5 answers


use

executed at compile time.

Instead, do:

BEGIN {
    if( $^O eq 'MSWin32' ) {
        require Win32::Process;
        # import Win32::Process qw(CREATE_NEW_CONSOLE);
        Win32::Process->import(qw/ CREATE_NEW_CONSOLE /);
    }
    else {
        #unix fork
    }
}

      

See perldoc for usage .

Also see perlvar on $^O

.




Update:

As Sinan Unur points out, it is best to avoid indirect object syntax .

I use direct method calls in every case except with calls import

. Probably because it import

disguises itself as inline. Since import

it is indeed a class method, it should be called as a class method.

Thank you Sinan.

Also, on Win32 systems, you have to be very careful to get the correct capitalization of your module names. Incorrect capitalization means that symbols will not be imported properly. It can get ugly. use win32::process

might seem to work fine.

+7


a source


Are you sure the win32 :: process can be loaded on OSX? "darwin" matches your / win / i.
You can use http://search.cpan.org/dist/Sys-Info-Base/ which tries to do the right thing.



As an aside, can you post the sample code you are using, the error message you are getting, and which unix platform (uname -a) is on?

+3


a source


How about a parser that modifies the file on every OS?

You can parse your perl file with a configure script that works on both operating systems to output perl with appropriate Use clauses. You can even bury the parsing action in the executable script to run the code.

I originally thought about precompiler directives from C, would do the trick, but I don't know perl very well.

0


a source


Here's the answer to your second set of questions:

Are you using strict

and warnings

?

Have you defined a subroutine ErrorReport()

? ErrorReport()

is just an example in the summary for Win32 :: Process .

CREATE_NEW_CONSOLE

is probably not numeric because it was not imported properly. Check the title entry when calling import

.

Compare these one-liners:

C:\>perl -Mwin32::process  -e "print 'CNC: '. CREATE_NEW_CONSOLE;
CNC: CREATE_NEW_CONSOLE

C:\>perl -Mwin32::process -Mstrict -e "print 'CNC: '. CREATE_NEW_CONSOLE;
Bareword "CREATE_NEW_CONSOLE" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

C:\>perl -MWin32::Process  -e "print 'CNC: '. CREATE_NEW _CONSOLE;
CNC: 16

      

0


a source


You can simply place your code on the platform inside eval{}

and check for a bug.

BEGIN{
  eval{
    require Win32::Process;
    Win32::Process->import(qw'CREATE_NEW_CONSOLE');
  };
  if( $@ ){ # $@ is $EVAL_ERROR

    # Unix code here

  }
}

      

0


a source







All Articles