问题
I am on Windows 10 using Strawberry Perl version 5.30 and trying to print out the values of the Registry key HKEY_CLASSES_ROOT/Directory/Background/shell/WSL
using the Perl module Win32::TieRegistry. Here is a screen shot from the Registry Editor app in Windows 10:
I am using this Perl script to print the value:
use feature qw(say);
use warnings;
use strict;
use Data::Dumper qw(Dumper);
use Win32::TieRegistry( Delimiter=>"/", ArrayValues=>0 );
{
dump_keys("HKEY_CLASSES_ROOT/Directory/Background/shell/WSL");
dump_keys("HKEY_CLASSES_ROOT/Directory/Background/shell/AnyCode");
}
sub dump_keys {
my ($key) = @_;
say "Dumping keys for $key:";
my $tree= $Registry->{$key};
my @keys = keys %$tree;
print Dumper(\@keys);
}
The output is (running from a CMD terminal with adminstration privileges):
>perl p.pl
Dumping keys for HKEY_CLASSES_ROOT/Directory/Background/shell/WSL:
$VAR1 = [];
Dumping keys for HKEY_CLASSES_ROOT/Directory/Background/shell/AnyCode:
$VAR1 = [
'command/',
'/'
];
as seen it prints the AnyCode
subkey but not the WSL
subkey. I also checked with running reg query
from the same CMD:
>reg query HKEY_CLASSES_ROOT\Directory\Background\shell\WSL
HKEY_CLASSES_ROOT\Directory\Background\shell\WSL
(Default) REG_SZ @wsl.exe,-2
Extended REG_SZ
NoWorkingDirectory REG_SZ
So that works fine, but why doesn't the Perl script print the value of the WSL
subkey?
回答1:
It turns out that even if you run the Perl script as admin, you do not necessarily have write access to a given registry key, see this blog post for more information.
According to the documentation for Win32::TieRegistry, the default $Registry
(the tied hash exported by Win32::TieRegistry
) is opened with both read and write access:
The virtual root of the Registry pretends it was opened with access
KEY_READ()|KEY_WRITE()
so this is the default access when opening keys directory via$Registry
This explains why some keys cannot be accessed from $Registry
since it when accessing a key the write permission is required.
As explained in the blog post it is possible to grant yourself write access to any key in the registry by using the regedit
app in Windows 10.
Another approach is to only require read access (not write access) when opening a tied hash with Win32::TieRegistry
:
use feature qw(say);
use warnings;
use strict;
use Data::Dumper qw(Dumper);
use Win32::RunAsAdmin qw(force);
use Win32API::Registry qw(regLastError KEY_READ);
use Win32::TieRegistry( Delimiter=>"/", ArrayValues=>0 );
{
my $reg = $Registry->Open("HKEY_CLASSES_ROOT/Directory",
{ Access=>KEY_READ(), Delimiter=>"/" }
);
dump_keys($reg, "Background/shell/WSL");
dump_keys($reg, "Background/shell/AnyCode");
}
sub dump_keys {
my ($reg, $key) = @_;
my $tree= $reg->{$key};
if (!$tree) {
say "failed: $^E";
}
else {
my @keys = keys %$tree;
print Dumper(\@keys);
}
}
来源:https://stackoverflow.com/questions/63031438/not-able-to-access-some-keys-in-registry-using-win32tieregistry