如何在Windows上运行Perl脚本时才能包含Win32模块?

时间:2009-05-21 16:51:39

标签: windows perl cross-platform

我有一个问题,我似乎无法找到答案。

使用Perl我需要在Windows和unix平台上使用脚本。问题是在Windows上我们使用Win32特定的模块,如Win32::Process,这些模块在unix上不存在。

我需要一种方法只在Windows上包含这些Win32模块。

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

问题在于windows的use语句。无论我尝试什么,这都不能在unix上编译。

我尝试过使用动态evals,要求,BEGIN等等。

这个问题有一个很好的解决方案吗?任何帮助将不胜感激。

提前致谢,


更新

一位同事向我指出这是正确的做法。

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";

谢谢大家的帮助!

5 个答案:

答案 0 :(得分:7)

use在编译时执行。

取而代之的是:

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
    }
}

请参阅perldoc for use

另请参阅$^O上的perlvar


<强>更新

正如Sinan Unur指出的那样,最好避免使用indirect object syntax

我在每种情况下都使用直接方法调用,但调用import除外。可能是因为import伪装成内置的。由于import实际上是一个类方法,因此应该将其称为类方法。

谢谢,思南。

此外,在Win32系统上,您需要非常小心,以使模块名称的大小写正确。大写不正确意味着将无法正确导入符号。它可能会变得丑陋。use win32::process似乎可以正常工作。

答案 1 :(得分:3)

你确定可以在OSX上加载win32 :: process吗? “darwin”与你/ win / i相匹配 您可能希望使用尝试做正确事情的http://search.cpan.org/dist/Sys-Info-Base/

除此之外,您是否可以发布您实际使用的代码示例,您收到的失败消息以及unix平台(uname -a)?

答案 2 :(得分:0)

在每个操作系统上修改文件的解析器怎么样?

您可以通过配置脚本解析perl文件,该脚本适用于两个操作系统,并使用正确的Use子句输出perl。您甚至可以将解析操作隐藏在可执行脚本中以启动代码。

最初我在想C中的预编译器指令可以解决问题,但我不太了解perl。

答案 3 :(得分:0)

以下是对第二组问题的回答:

您使用的是strictwarnings吗?

您是否定义了ErrorReport()子程序? ErrorReport()只是Win32::Process概要中的一个示例。

CREATE_NEW_CONSOLE可能不是数字,因为它没有正确导入。检查您对import

的通话中的大小写

比较这些单行:

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

答案 4 :(得分:0)

您可以将平台特定代码放在eval{}内,并检查错误。

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

    # Unix code here

  }
}