Strawberry Perl 和 PAR - 运行 其他 Windows 机器上的时间错误:如果安装了 LWP::Protocol::https 模块,LWP 将支持 https URL
Strawberry Perl and PAR - run time error on other Windows machine: LWP will support https URLs if the LWP::Protocol::https module is installed
我有两台 Windows 10 台机器,我在其中一台上安装了 Strawberry Perl(版本 5.30.1,如果重要的话)。我的脚本使用的是 REST::Client,在这台机器上,脚本 运行 非常完美。
我正在使用 PAR 制作 .exe
我可以 运行 .pl 脚本或 .exe 可执行文件;在这台机器上它 运行 完美。我在 运行 宁 pp.bat 时使用 --execute
选项,并包含一个 --xargs=
选项,以便脚本可以执行并 运行 成功。
然后我将 .exe 复制到另一台没有安装 Perl 的机器上。我使用相同的命令行选项启动 .exe,它编译正常并开始 运行。它做了一些工作,然后进行了第一个 REST GET。在这台没有安装 Strawberry Perl 的机器上,我收到一条消息 "The service reports a permanent error: LWP will support https URLs if the LWP::Protocol::https module is installed."
当然,我会收到 500 系列错误,因为 REST Web 服务对 GET 缺少 https:// 不满意。
还有一个错误:
The service reports a permanent error: Can't locate object method "new" via package "LWP::Protocol::https::Socket" at C:\foo\bar\AppData\Local\Temp\baz\qux\inc\lib/LWP/Protocol/http.pm line 34.
在我用来调用 pp.bat 的 .bat 文件中,我确实有 --module="LWP::Protocol::https"
- 尽管它是否存在似乎没有什么区别。
我看到了一些关于 LWP::UserAgent 和指定 protocols_allowed => ['https']
的文档,但我不确定应该如何在 REST::Client 中应用它。我试过把它放进去(并把它放在外面),结果是一样的。我的那部分代码如下所示:
my $client = REST::Client->new();
$client->addHeader( 'charset', 'UTF-8' );
$client->addHeader( 'Accept', 'application/xml' );
$client->addHeader( 'Authorization', $login_string );
$client->addHeader( 'Content-Type', 'application/xml' );
$client->getUseragent()->ssl_opts( verify_hostname => 0 );
$client->getUseragent()->ssl_opts( SSL_verify_mode => 0 );
$client->getUseragent( protocols_allowed => ['https'] );
$client->setTimeout( 10 );
$client->setHost( $host );
$client->GET( $url );
my $rest_client_reponse_code = $client->responseCode();
谁能看到我在这里遗漏了什么,并给我指点?
根据 this GitHub issue 中 Par::Packer 的维护者的说法:
PAR::Packer does not pack these non-Perl DLL dependencies. You can
either chase them done and explicitly pack them by hand with pp --link
..., [...]. Or use Shawn Laffan's App::PP::Autolink that does this for
you.
所以给出这个测试脚本p.pl
:
use strict;
use warnings;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $res = $ua->get( 'https://metacpan.org/pod/pp');
if ($res->is_success) {
print "ok\n";
}
else {
die $res->status_line;
}
您可以这样使用 App::PP::Autolink:
> pp_autolink -o p5.exe p.pl
Use of uninitialized value $_ in pattern match (m//) at C:\Strawberry\perl\site\lib/App/PP/Autolink.pm line 127.
Use of uninitialized value $_ in -e at C:\Strawberry\perl\site\lib/App/PP/Autolink.pm line 128.
DLL check iter: 1
DLL check iter: 2
DLL check iter: 3
Unable to locate these DLLS, packed script might not work:
Alien sys dlls added:
Detected link list: --link c:\strawberry\c\bin/libssl-1_1-x64__.dll --link c:\strawberry\c\bin/zlib1__.dll --link c:\strawberry\c\bin/libcrypto-1_1-x64__.dll
CMD:pp --link c:\strawberry\c\bin/libssl-1_1-x64__.dll --link c:\strawberry\c\bin/zlib1__.dll --link c:\strawberry\c\bin/libcrypto-1_1-x64__.dll -o p5.exe p.pl
正如您从上面的输出中看到的,我们缺少 libssl-1_1-x64__.dll
、zlib1__.dll
和 /libcrypto-1_1-x64__.dll
。将此 p5.exe
转移到另一台 Windows 10 机器现在工作正常。
我有两台 Windows 10 台机器,我在其中一台上安装了 Strawberry Perl(版本 5.30.1,如果重要的话)。我的脚本使用的是 REST::Client,在这台机器上,脚本 运行 非常完美。
我正在使用 PAR 制作 .exe
我可以 运行 .pl 脚本或 .exe 可执行文件;在这台机器上它 运行 完美。我在 运行 宁 pp.bat 时使用 --execute
选项,并包含一个 --xargs=
选项,以便脚本可以执行并 运行 成功。
然后我将 .exe 复制到另一台没有安装 Perl 的机器上。我使用相同的命令行选项启动 .exe,它编译正常并开始 运行。它做了一些工作,然后进行了第一个 REST GET。在这台没有安装 Strawberry Perl 的机器上,我收到一条消息 "The service reports a permanent error: LWP will support https URLs if the LWP::Protocol::https module is installed."
当然,我会收到 500 系列错误,因为 REST Web 服务对 GET 缺少 https:// 不满意。
还有一个错误:
The service reports a permanent error: Can't locate object method "new" via package "LWP::Protocol::https::Socket" at C:\foo\bar\AppData\Local\Temp\baz\qux\inc\lib/LWP/Protocol/http.pm line 34.
在我用来调用 pp.bat 的 .bat 文件中,我确实有 --module="LWP::Protocol::https"
- 尽管它是否存在似乎没有什么区别。
我看到了一些关于 LWP::UserAgent 和指定 protocols_allowed => ['https']
的文档,但我不确定应该如何在 REST::Client 中应用它。我试过把它放进去(并把它放在外面),结果是一样的。我的那部分代码如下所示:
my $client = REST::Client->new();
$client->addHeader( 'charset', 'UTF-8' );
$client->addHeader( 'Accept', 'application/xml' );
$client->addHeader( 'Authorization', $login_string );
$client->addHeader( 'Content-Type', 'application/xml' );
$client->getUseragent()->ssl_opts( verify_hostname => 0 );
$client->getUseragent()->ssl_opts( SSL_verify_mode => 0 );
$client->getUseragent( protocols_allowed => ['https'] );
$client->setTimeout( 10 );
$client->setHost( $host );
$client->GET( $url );
my $rest_client_reponse_code = $client->responseCode();
谁能看到我在这里遗漏了什么,并给我指点?
根据 this GitHub issue 中 Par::Packer 的维护者的说法:
PAR::Packer does not pack these non-Perl DLL dependencies. You can either chase them done and explicitly pack them by hand with pp --link ..., [...]. Or use Shawn Laffan's App::PP::Autolink that does this for you.
所以给出这个测试脚本p.pl
:
use strict;
use warnings;
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $res = $ua->get( 'https://metacpan.org/pod/pp');
if ($res->is_success) {
print "ok\n";
}
else {
die $res->status_line;
}
您可以这样使用 App::PP::Autolink:
> pp_autolink -o p5.exe p.pl
Use of uninitialized value $_ in pattern match (m//) at C:\Strawberry\perl\site\lib/App/PP/Autolink.pm line 127.
Use of uninitialized value $_ in -e at C:\Strawberry\perl\site\lib/App/PP/Autolink.pm line 128.
DLL check iter: 1
DLL check iter: 2
DLL check iter: 3
Unable to locate these DLLS, packed script might not work:
Alien sys dlls added:
Detected link list: --link c:\strawberry\c\bin/libssl-1_1-x64__.dll --link c:\strawberry\c\bin/zlib1__.dll --link c:\strawberry\c\bin/libcrypto-1_1-x64__.dll
CMD:pp --link c:\strawberry\c\bin/libssl-1_1-x64__.dll --link c:\strawberry\c\bin/zlib1__.dll --link c:\strawberry\c\bin/libcrypto-1_1-x64__.dll -o p5.exe p.pl
正如您从上面的输出中看到的,我们缺少 libssl-1_1-x64__.dll
、zlib1__.dll
和 /libcrypto-1_1-x64__.dll
。将此 p5.exe
转移到另一台 Windows 10 机器现在工作正常。