如何在WSL下安装CPAN Perl模块Win32API::Registry和Win32::TieRegistry(在Windows 11,64位上)?

ddarikpa  于 2023-04-12  发布在  Perl
关注(0)|答案(2)|浏览(273)

我正在尝试安装Win32::TieRegistry,以便在我将在WSL中运行的Perl程序中使用(在emacs下)。有关我在最后编写的Perl程序的详细信息。我看到上面的模块应该让我从Perl查询Windows注册表。
我在cpan中得到以下错误:

cpan[16]> install Win32API::Registry

Running install for module 'Win32API::Registry'
  CHORNY/Win32API-Registry-0.33.tar.gz
  Has already been unwrapped into directory /home/cfclark/.cpan/build/Win32API-Registry-0.33-0
  CHORNY/Win32API-Registry-0.33.tar.gz
  '/usr/bin/perl Makefile.pl INSTALLDIR$=site' returned status 65280, not re-running

cpan[17]> install Win32::TieRegistry

Running install module 'Win32::TieRegistry'
  CHORNY/Win32-TieRegistry-0.30.tar.gz
  Has already been unwrapped into directory /home/cfclark/.cpan/build/Win32-TieRegistry-0.30-1
  CHORNY/Win32-TieRegistry-0.30.tar.gz
  Has already been prepared
  CHORNY/Win32-TieRegistry-0.30.tar.gz
  Has already been made
Running make test for CHORNY/Win32-TieRegistry-0.30.tar.gz
PERL_DL_NONLAZY=1 "/usr/bin/perl" "-MExUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01_compile.t .. skipped: Not testing on non-Windows
t/02_main.t .... Can't locate Win32API/Registry.pm in @INC (you may need to install the Win32API::Registry module) (@INC contains: /home/cfclark/.cpan/build/Win32-TieRegistry-0.30-1/blib/lib  /home/cfclark/.cpan/build/Win32-TieRegistry-0.30-1/blib/arch  /home/cfclark/.cpan/build/YAML-1.30-1/blib/arch <and a bunch more directories but not ones for Win32-TieRegistry-0.30-0>
BEGIN failed--compilation aborted at t/02/main.t line 17.
t/02_main.t .... Dubious, test returned 2 (wstat 513, 0x200)
No subtests run

我的目标是转换一个Windows .cmd文件,它可以从Windows注册表中获取一些数据(使用reg查询)转换成我可以运行的Perl程序我最初尝试将.cmd脚本转换为BASH,但我需要对注册表输出进行一些正则表达式操作,这些操作在Perl中更容易完成。('reg.exe','query'.....),但这似乎永远不会返回到emacs shell,即perl程序只是挂起后,该系统命令。
无论如何,问题似乎是安装Win32 API::Registry失败,它拒绝重新安装它。因此,相关目录从未添加到@INC搜索路径。然而,我不知道如何告诉cpan解决这个问题。

ddhy6vgd

ddhy6vgd1#

这些模块可以调用Windows系统。你不能在Linux中安装它们。Linux甚至没有注册表的概念。
你必须在你想更改注册表的Windows机器上做你想做的事情(例如使用Strawberry Perl),而不是在Linux机器上。
可以远程编辑注册表。我不知道需要什么要求。(例如,您需要在客户端上安装某个版本的Windows吗?两台机器都需要连接到同一个域吗?)我不知道从Linux可以使用什么工具来做这件事,如果有的话。这不是我推荐的路线。

uxhixvfz

uxhixvfz2#

由于@ikegami指出的原因,我不能在Linux中使用Windows API,我有一个粗略的解决方案,让我在WSL中运行的Perl脚本从它运行的Windows机器上读取感兴趣的注册表值。这不是很漂亮,但它可以工作。
首先,Perl代码:

use feature 'signatures';
sub GetRegistryValue($registry, $query_suffix, $value) {
  my $results = qx( "pathtobashscript/regquery ${registry}, ${query_suffix}, ${value}" );
  # check $? here for errors, code omitted, but the script returns 0 on found
  return $results;
}

现在,bash脚本'regquery'(最难的部分):

#!/bin/bash
set -e
set -o pipefail
trap 'exit 1' 1 2 3 13 15
reg.exe query "$1\\$2" /v "$3" |& cat
trap 1 2 3 13 15
exit 0

perl中的用法示例:

my $reg_value = GetRegistryValue('HKLM', 
    "\"SOFTWARE\\\\Microsoft\\\\VisualStudio\\\\SxS\\\\VS7\"", '"14.0"');

我可能已经能够避免第二个参数中的一些反斜杠地狱,但这来自于调整它,直到我找到足够的东西来通过,Perl,Bash,可能还有Windows需求。
一些关键的问题,在bash脚本中没有cat命令,WSL并不总是干净地返回Perl调用者(也不返回Emacs shell缓冲区)。然而,由于该管道,您需要捕获管道故障的代码,并在reg.exe命令失败时返回退出状态。否则,cat命令的管道会隐藏该状态。
注意,reg.exe似乎总是在我的路径中,但如果它不在你的路径中,你可能需要使用特定的Windows路径。在StackOverflow上有一个例子,但这不是我的问题。
请注意,我从(How do you catch error codes in a shell pipe?)中抄袭了trap命令的StackOverflow代码在要捕获的信号列表中列出了0,但由于管道的存在,它创建了一个子shell,您获得了该信号,脚本向Perl返回错误代码256,从列表中删除0可以避免该问题。
结果中有一些文本我仍然需要过滤,这也是我首先使用Perl的原因,但是我现在有了以前依赖于嵌套的.cmd文件获取的值。
如果有人知道如何在Perl中完成这一切(在WSL中运行的Emacs中运行,而不是在Windows上),这样我就可以避免bash脚本,我会有兴趣看看它是如何工作的。

相关问题