如何跨平台使用Win32 :: Console及其常数? [英] How can I optionally use Win32::Console and its constants in a cross platform way?

查看:179
本文介绍了如何跨平台使用Win32 :: Console及其常数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我正在使用Perl v5.8.4,但我没有能力升级Perl或安装 Term :: ReadKey IO :: Prompt (或实际上不是Core内的任何东西),因此在回答/评论时请考虑这一点。

To start with, I'm working Perl v5.8.4 and I DO NOT have the ability to upgrade Perl or install Term::ReadKey or IO::Prompt (or really anything outside of what is in Core), so please take that into consideration when answering/commenting.

我正在尝试编写一个完全自包含的Perl脚本,该脚本(除其他外)提示输入密码。它需要在Windows,AIX和Solaris之间跨平台兼容。我不希望它在输入密码时回显密码。这是我的东西:

I'm trying to write a completely self contained Perl script that (among other things) prompts for a password. It needs to be cross platform compatible between Windows, AIX, and Solaris. I don't want it to echo the password as it is typed. Here's what I have:

BEGIN {
    if ($^O eq 'MSWin32') {
        require Win32::Console; 
        Win32::Console->import();
    }
}
sub get_password {
    print "Enter password: ";
    my $pass = '';
    # Change terminal settings to not display password
    if ($os eq 'MSWin32') {
        my $stdin = new Win32::Console STD_INPUT_HANDLE;
        my $orig_mode = $stdin->Mode();
        $stdin->Mode(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | +ENABLE_MOUSE_INPUT);
        chomp($pass = <STDIN>);
        $stdin->Mode($orig_mode);
    }
    else {
        system('stty', '-echo');
        chomp($password = <STDIN>);
        system('stty', 'echo');
    }
    print "\n";
    return $pass;
}

在所有平台上都可以正常工作(假设我不 use strict ),但是,Win32块中使用的4个常量对Unix上的 strict子抛出错误:

This works perfectly fine on all platforms (assuming I don't use strict), however, the 4 constants used in the Win32 block throw errors against strict subs on Unix:

Bareword "STD_INPUT_HANDLE" not allowed while "strict subs" in use at script.pl line 488.
Bareword "ENABLE_LINE_INPUT" not allowed while "strict subs" in use at script.pl line 490.
Bareword "ENABLE_PROCESSED_INPUT" not allowed while "strict subs" in use at script.pl line 490.
Bareword "ENABLE_MOUSE_INPUT" not allowed while "strict subs" in use at script.pl line 490.

了解如何使Windows和Unix对这4个常量感到满意。如果我尝试在仅Unix块中定义它们,则Windows编译器会告诉我正在重新定义它们。

I can't for the life of me figure out how to make both Windows and Unix be happy with those 4 constants. If I try to define them in a Unix only block, the Windows compiler tells me that I'm redefining them.

我可以解决此问题吗?还是用另一种方式呢?预先感谢您的帮助。

Can I fix this? Or perhaps do it in another way? Thanks in advance for the help.

推荐答案

您必须使用parens对未声明的子例程进行子例程调用。因此,要么通过更改

You must use parens for subroutine calls to subroutines you haven't declared. So either add parens by changing

STD_INPUT_HANDLE
ENABLE_LINE_INPUT
...

STD_INPUT_HANDLE()
ENABLE_LINE_INPUT()
...

或在需要时声明子例程不会由Win32 :: Console声明,方法是更改​​

or declare the subroutines when they wouldn't be declared by Win32::Console by changing

    if ($^O eq 'MSWin32') {
        require Win32::Console; 
        Win32::Console->import();
    }

    if ($^O eq 'MSWin32') {
        require Win32::Console; 
        Win32::Console->import();
    } else {
        eval <<'__EOI__'.';1' or die $@;
            sub STD_INPUT_HANDLE  { die }
            sub ENABLE_LINE_INPUT { die }
            ...
__EOI__
    }

更清洁的方法是将特定于操作系统的代码移到单独的模块中。

A cleaner approach would be to move the OS-specific code into separate modules.

BEGIN {
    my $mod = $^O eq 'MSWin32' ? 'My::IO::Win32' : 'My::IO::Default';
    eval "require $mod" or die $@;
    $mod->import(qw( get_password ));
}

这篇关于如何跨平台使用Win32 :: Console及其常数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆