Search code examples
perlwinapiregistrytie

Why can't Win32::TieRegistry list subkeys?


Using Cygwin Perl v5.8.8 and Win32::TieRegistry 0.26.

We can get a tied hash object thing for HKEY_CURRENT_USER:

$ perl -e '
my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_CURRENT_USER"};
print Dumper $Key;'
$VAR1 = bless( {}, 'Win32::TieRegistry' );

And this works for sub keys:

$ perl -e '
my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_CURRENT_USER\\Software"};
print Dumper $Key;'
$VAR1 = bless( {}, 'Win32::TieRegistry' );

And we can print information for the key:

$ perl -e '
my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_CURRENT_USER\\Software"};
print Dumper $Key->Information;'
$VAR1 = 'CntSubKeys';
$VAR2 = 48;
$VAR3 = 'MaxSubClassLen';
$VAR4 = 21;
...

However the documentation implies we can list the sub keys simply by treating it as a hash:

$ perl -e '
my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_CURRENT_USER\\Software"};
print Dumper keys %$Key; '

But the array is empty. Is it broken or am I doing something wrong? Is there another way to list the sub keys?

This doesn't work either:

$ perl -e '
my %RegHash;
use Win32::TieRegistry( TiedHash => \%RegHash );
use Data::Dumper;
my $Key = $RegHash{"HKEY_CURRENT_USER\\Software"};
print Dumper $Key->SubKeyNames;'
Can't use an undefined value as an ARRAY reference at
/usr/lib/perl5/vendor_perl/5.8/cygwin/Win32/TieRegistry.pm line 720.

Solution

  • With your code:

    my %RegHash;
    use Win32::TieRegistry( TiedHash => \%RegHash );
    use Data::Dumper;
    my $Key = $RegHash{"HKEY_CURRENT_USER\\Software"};
    print Dumper keys %$Key;
    

    I get this result on my machine (WinXP, ActiveState Perl v5.10.0, Win32-TieRegistry 0.25):

    $VAR1 = 'Adobe\\';
    ...
    $VAR101 = 'Classes\\';
    $VAR102 = '\\';
    

    and this is what I get with your second code sample:

    $VAR1 = 'Adobe';
    ...
    $VAR101 = 'Classes';
    

    So both of your code samples work okay, on ActiveState Perl and Windows XP at least.

    EDIT: This looks like a more general problem/bug: