Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Win32::TieRegistry Error (or is it me?)

by ChrisR (Hermit)
on Sep 27, 2005 at 02:13 UTC ( [id://495251]=perlquestion: print w/replies, xml ) Need Help??

ChrisR has asked for the wisdom of the Perl Monks concerning the following question:

I have a small routine that reads code from the registry. This code has worked just fine but today it began giving me trouble. The registry data didn't change. The code that reads it didn't change. I upgraded Win32::API to version .41 because I needed to use Win32::API::Struct in another program and immediately began getting this error:

Can't use an undefined value as an ARRAY reference at C:/Perl/site/lib/Win32/TieRegistry.pm line 685, <DATA> line 164.

I'm using Win32::TieRegistry version .24 and actually removed it and re-installed it after the error began but it didn't help. Can this be caused by something that has changed in Win32::API? Probably not but it's the only thing that changed. The compiled (standalone) vserion of this program still works.

Here's the code that reads the registry:

$Key = $Registry->Open( "LMachine/Software/Vibac_Calls/CallsList/F +ields", {Access=>KEY_READ(),Delimiter=>"/"} ) or warn "OPEN: $Key -> +(ERROR: $^E)\n"; my @regFields = $Key->SubKeyNames; $data_mycalls{fields} = (); for my $x(0..$#regFields) { my $fieldKey = $Registry->Open( "LMachine/Software/Vibac_Calls +/CallsList/Fields/$regFields[$x]", {Access=>KEY_READ(),Delimiter=>"/" +} ) or warn "OPEN: $Key -> (ERROR: $^E)\n"; #print (join " ", keys %{$fieldKey}) . "\n"; my @regValues = $fieldKey->ValueNames; #THIS IS THE LINE IN MY + CODE WHERE THE ERROR APPEARS for my $y(0..$#regValues) { $data_mycalls{fields}[$x]{$regValues[$y]} = $fieldKey->Get +Value($regValues[$y]); } }
When I was trying to debug the problem, I found that the error was being thrown right before calling ValueNames on the last key. When I added this simple debug line (that is commented in my code above)
print (join " ", keys %{$fieldKey}) . "\n";
the error went away. It prints the values out as expected and the program continues. There are 7 keys that get looped through and each key has the same 11 values with slightly different data. This problem only happens on the last key. If I add an eighth key with no sub keys, I don't have this problem.

I took a look at Win32::TieRegistry to see where the error came from.

sub _enumValues { my $self= shift(@_); $self= tied(%$self) if tied(%$self); my( @names )= (); my $pos= 0; my $name= ""; my $nlen= 1+$self->Information("MaxValNameLen"); while( $self->RegEnumValue($pos++,$name,$nlen,[],[],[],[]) ) { push( @names, $name ); } if( ! _NoMoreItems() ) { return (); } $self->{VALUES}= \@names; return 1; } sub ValueNames { my $self= shift(@_); $self= tied(%$self) if tied(%$self); @_ and croak "Usage: \@names= \$key->ValueNames;"; $self->_enumValues unless $self->{VALUES}; return @{$self->{VALUES}}; #THIS IS THE LNE THAT THROWS THE ERROR }
But, of course, I couldn't find anything wrong there either.

Here's an export of the registry in case anyone's interested in seeing the data:

Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields] [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\0] "field"="calls.id" "header"="ID" "visible"="1" "width"="32" "type"="" "recordlink"="" "displaylink"="" "sort"="ASC" "sorttype"="number" "displaypos"="0" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\1] "field"="calls.caller" "header"="Caller" "visible"="1" "width"="100" "type"="" "recordlink"="users2.id" "displaylink"="users2.fullname" "sort"="" "sorttype"="text" "displaypos"="1" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\2] "field"="calls.responder" "header"="Responder" "visible"="0" "width"="100" "type"="" "recordlink"="users2.id" "displaylink"="users2.fullname" "sort"="" "sorttype"="text" "displaypos"="2" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\3] "field"="calls.details" "header"="Details" "visible"="1" "width"="240" "type"="" "recordlink"="" "displaylink"="" "sort"="" "sorttype"="text" "displaypos"="3" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\4] "field"="calls.resolution" "header"="Resolution" "visible"="1" "width"="182" "type"="" "recordlink"="" "displaylink"="" "sort"="" "sorttype"="text" "displaypos"="4" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\5] "field"="calls.time" "header"="CallDate" "visible"="1" "width"="109" "type"="" "recordlink"="" "displaylink"="" "sort"="ASC" "sorttype"="number" "displaypos"="5" [HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\6] "field"="calls.closed" "header"="Closed" "visible"="1" "width"="40" "type"="check" "recordlink"="" "displaylink"="" "sort"="" "sorttype"="number" "displaypos"="6"

Replies are listed 'Best First'.
Re: Win32::TieRegistry Error (or is it me?) (leads)
by tye (Sage) on Sep 27, 2005 at 02:33 UTC

    The getting of the list of values is ending with a reason other than "no more values to get". It is a bug (in the module) that this causes the module to die.

    You could wrap the call to ValueNames() in eval and after that report $^E or Win32API::Registry::regLastError() to get a hint what the problem is. Let me know what that reports.

    These modules don't use Win32::API so I doubt your update of it is the source of the change.

    - tye        

      I was pretty sure that it wasn't the upgrade but that was the only that changed.

      Here's what I did:

      eval { @regValues = $fieldKey->ValueNames; }; print "\$\^E: $^E\nregLastError: " . Win32API::Registry::regLastError( +) ."\n\n";
      The program did not die and here's what was printed:
      $^E: regLastError: No more data is available
      Without the eval:
      @regValues = $fieldKey->ValueNames; print "\$\^E: $^E\nregLastError: " . Win32API::Registry::regLastError( +) ."\n\n";
      the program dies and prints this:
      $^E: No more data is available regLastError: No more data is available Can't use an undefined value as an ARRAY reference at C:/Perl/site/lib +/Win32/TieRegistry.pm line 684, <DATA> line 164.
      However, I may not have used eval correctly or as you intended. If not let me know and I'll do it again.

      Thanks,
      Chris

        Okay, that makes it look like Win32::WinError got changed. What does this produce?

        perl -MWin32::WinError -le"print Win32::WinError::constant("ERROR_NO_M +ORE_ITEMS",0)" perl -MWin32::WinError=999 -e0

        - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://495251]
Approved by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-18 01:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found