perl - 当 stdin/stderr/stdout 在 Activestate Perl 中重定向时写入控制台

标签 perl winapi console windows-console activestate

我有以下代码要写入 Windows 命令控制台:

use Win32::Console;
my $console = new Win32::Console(Win32::Console::STD_ERROR_HANDLE());
my $defaultAttribute = $console->Attr();
my $defaultFG = ($defaultAttribute & 0x0F);
my $defaultBG = ($defaultAttribute & 0xF0);
$console->Attr($defaultBG | $Win32::Console::FG_LIGHTGREEN);
$console->Write("blah blah");
$console->Attr($defaultAttribute);

如果用户在调用我的脚本时重定向 STDERR,此代码将失败:

perl myscript.pl 2> foo

如何获取进程所附加的 Win32 控制台的句柄而不引用标准句柄之一,以便用户进行什么重定向都无关紧要?

我想要的效果是能够在正常程序输出之后立即在控制台上写入一条消息,而不管任何重定向如何,与 bash 内置 time 命令类似。本质上,类似于在 Unix 中打开并写入 /dev/tty

我尝试过 my $console = new Win32::Console() 分配一个新控制台,然后分配 $console->Display() 但这完全有效错误的事情。

最佳答案

问完这个问题后,我进行了更深入的研究,并通过使用令人讨厌的 hack 解决了它:

use Win32API::File qw(createFile);
use Win32::Console;

my $handle = createFile('CONOUT$', 'rwke') or die "conout\$: $^E\n";
# my $console = new Win32::Console($handle) or die "new console: $^E\n";
my $console = bless {handle => $handle}, 'Win32::Console';

我查看了 new() 的代码里面的功能Win32::Console并看到它只是创建一个包含控制台句柄的哈希。如果参数指定 stdin/stdout/stderr,它只会检索关联的句柄,否则它会创建一个新的控制台屏幕缓冲区并使用该句柄。

所以我只是手动创建了 Win32::Console包含 CreateFile 返回的控制台句柄的对象。

现在perl myscript.pl > nul 2> nul < nul会写blah blah在紧邻命令行下方的屏幕上。

如果有人提出更好的答案,我会接受。

关于perl - 当 stdin/stderr/stdout 在 Activestate Perl 中重定向时写入控制台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14842131/

相关文章:

php - 如何通过交互调用 artisan 控制台命令

JavaFX:控制台登录 TextArea + 多线程和任务

arrays - 如何在@array2 中查找值而不是在@array1 中查找值

perl - 不推荐使用散列作为引用

xml - 使用 xml_grep 访问 XPath 指定的属性

c++ - attachconsole的问题

Python自动化Outlook电子邮件: change sender or default reply-to address

windows - 如何显示 'Send to' 和 'Open With' 上下文菜单?

perl - 获取 Word 文档特定部分中的段落

java - 使用 Intellij 和 JUnit 从控制台读取 System.in