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
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.
a source to share
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?
a source to share
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.
a source to share
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
a source to share