windows 如何在从 Win32::Process 启动的 Perl 进程中获取输出?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1318447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:01:38  来源:igfitidea点击:

How do I get output in a Perl process started from Win32::Process?

windowsperlwinapi

提问by Naseer

I have a Perl script that launches another Perl script in a new console through Win32::Processas follows:

我有一个 Perl 脚本,它通过Win32::Process在新控制台中启动另一个 Perl 脚本,如下所示:

Win32::Process::Create($ProcessObj,
                      "C:\Perl\bin\perl.exe",
                      "$path_to_other_perl_script",
                      0,
                      NEW_CONSOLE,
                      ".");

$ProcessObj->Suspend();
$ProcessObj->Resume();
$ProcessObj->Wait(0);

The problem is, there is no stdout in the new console created. If I don't use the new console option, the script runs silently in the background.

问题是,创建的新控制台中没有标准输出。如果我不使用新的控制台选项,脚本将在后台静默运行。

If I use cmd.exe to launch the Perl script, I can see the output fine but now I cannot control the child Perl script through Win32::Process.

如果我使用 cmd.exe 启动 Perl 脚本,我可以很好地看到输出,但现在我无法通过 Win32::Process 控制子 Perl 脚本。

Does anyone have a solution that works?

有没有人有一个有效的解决方案?

回答by Sinan ünür

Update:Based on your comments, I get the feeling that your programs are not examples of best practices on Linux or Windows. However, I am sure, when reading the documentation for Win32::Process, you noticed that you can call the Killmethod on the process to terminate it. So, I changed the example below to do that.

更新:根据您的评论,我觉得您的程序不是 Linux 或 Windows 上最佳实践的示例。但是,我敢肯定,在阅读 的文档时Win32::Process,您会注意到可以调用Kill进程上的方法来终止它。所以,我改变了下面的例子来做到这一点。

Your chances of getting useful help increase exponentially if you provide real code. Here are the arguments to Win32::Process::Create:

如果您提供真实的代码,您获得有用帮助的机会会成倍增加。以下是 的论据Win32::Process::Create

$iflags:flag: inherit calling processes handles or not

$iflags:flag: 是否继承调用进程句柄

Now, I am not sure if you are trying to capture the STDOUTof the second process or if you are trying to have its STDOUToutput show up in the same console as the parent.

现在,我不确定您是要捕获STDOUT第二个进程的 ,还是要使其STDOUT输出显示在与父进程相同的控制台中。

If the latter, then the following scripts illustrate one way of doing that:

如果是后者,那么以下脚本说明了一种方法:

parent.pl

父母.pl

#!/usr/bin/perl

use strict;
use warnings;

use Win32;
use Win32::Process;

$| = 1;

my $p;

print "Starting child process ... \n";

Win32::Process::Create(
    $p,
    'c:/opt/perl/bin/perl.exe',
    'perl hello.pl',
    1,
    NORMAL_PRIORITY_CLASS,
    '.',
) or die Win32::FormatMessage( Win32::GetLastError() );

print "Waiting three seconds before killing 'hello.pl'\n";

for (1 .. 3) {
    print;
    sleep 1;
}
$p->Kill(0)
    or die "Cannot kill '$p'";

hello.pl

你好.pl

#!/usr/bin/perl

$| = 1;

print "Hello World\n";
print "Sleeping 1000 seconds\n";

for (1 .. 1000) {
    sleep 1;
    print '.';
}

Output:

输出:

Starting child process ...
Waiting three seconds before killing 'hello.pl'
1Hello World
Sleeping 1000 seconds
2.3.

Now, I am still not sure why you are using Win32::Process. Unless there is a specific reason to tie your script to Win32, I would recommend using standard Perl facilities. For example, read perldoc -f openand perldoc perlipc(see esp. Using open for IPC).

现在,我仍然不确定您为什么使用Win32::Process. 除非有特定的理由将您的脚本绑定到Win32,否则我建议使用标准的 Perl 工具。例如,阅读perldoc -f openperldoc perlipc(参见 esp. Using open for IPC)。

Explain your question better to get answers that address your particular situation rather than generalities.

更好地解释您的问题以获得针对您的特定情况而非一般情况的答案。

回答by Naseer

Using -w before $filepath fixed it ! Still need an explanation though.

在 $filepath 修复它之前使用 -w !不过还是需要解释一下。